
假設我有 2 個獨立的循環
for file1 in `ls Dir1/` ; do
echo $file1
done
for file2 in `ls Dir2/` ; do
echo $file2
done
我想要單循環迭代兩個目錄偽代碼
for file1 , file2 in `ls Dir1` , `ls Dir2`
do
echo $file1
echo file2
done
是否可以
答案1
while
假設檔案名稱中沒有換行符,具有適當輸入的循環可以完成這項工作。
paste -d/ <(ls /var) <(ls /usr) |
while IFS=/ read -r e u; do
printf '%s\n' "$e $u"
done
答案2
shopt -s nullglob
dir1names=( Dir1/* )
dir2names=( Dir2/* )
while [ "${#dir1names[@]}" -gt 0 ] &&
[ "${#dir2names[@]}" -gt 0 ]
do
printf '%s\n' "${dir1names[0]##*/}"
printf '%s\n' "${dir2names[0]##*/}"
dir1names=( "${dir1names[@]:1}" )
dir2names=( "${dir2names[@]:1}" )
done
這用於bash
將每個目錄中的所有路徑名稱獲取到兩個數組中。然後,它在陣列之間交替列印這些路徑名稱的檔案名稱部分(就像ls
所做的那樣),並從陣列中刪除列印的整體。當其中一個數組完全為空時,它會停止。
shellnullglob
選項使不匹配的通配模式展開為空,而不是保持不展開。
測試:
$ tree
.
|-- Dir1
| |-- file-1
| |-- file-2
| |-- file-3
| `-- file-4
|-- Dir2
| |-- otherfile-1
| |-- otherfile-2
| |-- otherfile-3
| |-- otherfile-4
| |-- otherfile-5
| `-- otherfile-6
`-- script.sh
2 directories, 11 files
$ bash script.sh
file-1
otherfile-1
file-2
otherfile-2
file-3
otherfile-3
file-4
otherfile-4
如果這是實際上關於根據文件名稱將文件配對,以便一個目錄中的文件與另一個目錄中的相應文件配對(似乎有時在生物資訊應用程式中完成),那麼您最好只迭代其中一個集合進而建造另一組中對應文件的名稱。
假設文件被調用something_R1_more
並且something_R2_more
在哪裡something
並且more
正在識別特定的文件R1
對R2
。
for r1 in dir1/*_R1_*; do
r2=${r1##*/} # dir1/something_R1_more --> something_R1_more
r2=dir2/${r2/_R1_/_R2_} # something_R1_more --> dir2/something_R2_more
if [ ! -f "$r2" ]; then
printf '%s not found\n' "$r2" >&2
exit 1
fi
# process "$r1" and "$r2" here
done
答案3
你一般不想解析的輸出ls
。
在這裡,zsh
(您已經在使用zsh
語法,而不是bash
因為您沒有引用變數並使用命令替換而不禁用通配符),您可以這樣做:
dir1_file_names=(dir1/*(N:t))
dir2_file_names=(dir2/*(N:t))
for f1 f2 (${dir1_file_names:^dir2_file_names})
printf '%s\n' "f1: $f1, f2: $f2"
zsh
可以循環多個變數。${a:^b}
是一個數組壓縮操作員。如果其中一個陣列的元素少於另一個陣列的元素,則好像它們被截斷為最小的長度一樣。
如果要比較兩個目錄中的檔案名,請另參閱其陣列交集和減法運算子:
file_names_in_both_dir1_and_dir2=(${dir1_file_names:*dir2_file_names})
file_names_only_in_dir1=(${dir1_file_name:|dir2_file_names})
file_names_only_in_dir2=(${dir2_file_name:|dir1_file_names})
答案4
多個變數的輸出可以保存在單一變數中,如下所述。檢查它是否適合您
#!/bin/bash
cd /
for file1 in $(ls /usr/ ; echo "::::::NEXT:::::::" ; ls /sys/)
do
echo $file1
done