亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何循環查找返回的文件名?

如何循環查找返回的文件名?

繁花不似錦 2019-07-19 15:16:45
如何循環查找返回的文件名?x=$(find . -name "*.txt")echo $x如果我在Bashshell中運行上面的代碼,我得到的是一個包含幾個文件名的字符串,該字符串由空白分隔,而不是一個列表。當然,我可以用空白將它們分開,以獲得一個列表,但我確信有更好的方法。那么,循環遍歷find指揮部?
查看完整描述

3 回答

?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

如果你只是為了最正確的答案而來,你可能想要我個人的偏好,find . -name '*.txt' -exec process {} \;(見這篇文章的底部)。如果你有時間的話,把剩下的部分讀一遍,看看幾種不同的方法,以及它們中大多數的問題。


完整的答案是:

最好的方法取決于你想做什么,但這里有幾個選擇。只要子樹中沒有文件或文件夾的名稱中有空格,您就可以遍歷這些文件:

for i in $x; do # Not recommended, will break on whitespace
    process "$i"done

稍微好一點,去掉臨時變量x:

for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
    process "$i"done

它是你最好在可能的時候笑一笑。空白保險箱,用于當前目錄中的文件:

for i in *.txt; do # Whitespace-safe but not recursive.
    process "$i"done

通過啟用globstar選項,您可以在此目錄和所有子目錄中顯示所有匹配的文件:

# Make sure globstar is enabledshopt -s globstarfor i in **/*.txt; do # Whitespace-safe and recursive
    process "$i"done

在某些情況下,例如,如果文件名已經在文件中,則可能需要使用read:

# IFS= makes sure it doesn't trim leading and trailing whitespace# -r prevents interpretation of \ escapes.while IFS= read -r line; do # Whitespace-safe EXCEPT newlines
    process "$line"done < filename

read可安全結合使用find通過適當設置分隔符:

find . -name '*.txt' -print0 | 
    while IFS= read -r -d '' line; do 
        process $line    done

對于更復雜的搜索,您可能需要使用find,不管是用它-exec選項或有-print0 | xargs -0:

# execute `process` once for each filefind . -name \*.txt -exec process {} \;# execute `process` once with all the files as arguments*:find . -name \*.txt -exec process {} +# using xargs*find . -name \*.txt -print0 | xargs -0 process# using xargs with arguments after each filename (implies one run per filename)find . -name \*.txt -print0 | xargs -0 -I{} process {} argument

find還可以在運行命令之前將CD光盤到每個文件的目錄中。-execdir而不是-exec,并且可以使用以下命令進行交互(在運行每個文件的命令之前提示符)-ok而不是-exec(或-okdir而不是-execdir).

*:技術上,兩者都是findxargs(默認情況下)將在命令行中使用盡可能多的參數來運行該命令,并盡可能多地運行該命令以獲得所有文件。實際上,除非您有大量的文件,否則這并不重要,而且如果您超過了長度,但是需要在同一個命令行中所有這些文件,你是索爾找個不同的方法。


查看完整回答
反對 回復 2019-07-19
?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

find . -name "*.txt"|while read fname; do
  echo "$fname"done

注:此方法bmarguies顯示的(第二個)方法在文件/文件夾名稱中的空白中使用是安全的。

為了在所涵蓋的文件/文件夾名稱中有一些異國情調的換行符,您將不得不求助于-exec謂語find就像這樣:

find . -name '*.txt' -exec echo "{}" \;

這個{}是已找到項的占位符,而\;用于終止-exec謂詞

為了完整起見,讓我添加另一個變體-你必須喜歡*nix方式,因為它們的多功能性:

find . -name '*.txt' -print0|xargs -0 -n 1 echo

這將印刷品與\0據我所知,在任何文件系統中都不允許使用文件名或文件夾名中的字符,因此應該涵蓋所有的基礎。xargs然后一個接一個地撿起來.。


查看完整回答
反對 回復 2019-07-19
?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

不管你做什么,不要使用for環路:

# Don't do thisfor file in $(find . -name "*.txt")do
    …code using "$file"done

三個原因:

  • 如果for循環甚至要啟動,則

    find

    必須完成。
  • 如果一個文件名中有任何空格(包括空格、制表符或換行符),那么它將被視為兩個單獨的名稱。
  • 盡管現在不太可能,但您可以溢出命令行緩沖區。假設您的命令行緩沖區包含32 KB,而您的

    for

    循環返回40 kb的文本。最后的8KB將從你的

    for

    循環你永遠也不會知道。

始終使用while read建造:

find . -name "*.txt" -print0 | while read -d $'\0' filedo
    …code using "$file"done

循環將在find命令正在執行。此外,即使返回帶有空格的文件名,該命令也能工作。并且,您不會溢出命令行緩沖區。

這個-print0將使用NULL作為文件分隔符,而不是換行符,-d $'\0'讀取時將使用NULL作為分隔符。


查看完整回答
反對 回復 2019-07-19
  • 3 回答
  • 0 關注
  • 451 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號