【问题标题】:How to assign all the files listed in a directory to a filelist using shell script?如何使用 shell 脚本将目录中列出的所有文件分配给文件列表?
【发布时间】:2016-05-18 16:31:19
【问题描述】:

我需要比较目录中可用的文件,只有当我在文件列表中单独提及文件名(file1 file2 file3 file4)时,以下代码才能正常工作

#!/bin/bash

filelist=(file1 file2 file3 file4) 


# Outer for loop
for (( i=0; i<${#filelist[@]} ; i+=1 )) ; do
    # Inner for loop
    for (( j=i+1; j<${#filelist[@]} ; j+=1 )) ; do

    echo "Unique between ${filelist[i]}" "${filelist[j]}" > unique${filelist[i]}${filelist[j]}.txt

    echo -e "Unique in ${filelist[i]}"  >> unique${filelist[i]}${filelist[j]}.txt

    # Will produce unique lines in 'file i' when comparing 'file i' and 'file j'
    join -v 1 <(sort ${filelist[i]}) <(sort ${filelist[j]}) >> unique${filelist[i]}${filelist[j]}.txt

    echo -e "Unique in  ${filelist[j]}" >> unique${filelist[i]}${filelist[j]}.txt

    # Will produce unique lines in 'file j' when comparing 'file i' and 'file j'
    join -v 2 <(sort ${filelist[i]}) <(sort ${filelist[j]}) >> unique${filelist[i]}${filelist[j]}.txt

    done

done

但我真正想要的是将目录中可用的文件直接分配给文件列表。请问有什么可行的解决方案吗?

【问题讨论】:

  • 如果文件名有空格,您接受的答案将不会给出正确的结果。你可以验证它。只有我的答案是正确的。
  • 验证:mkdir -p /tmp/test && cd test && touch List\ s && filelist=($(/bin/ls)) && shuf -e "${filelist[@]}"
  • 您将看到 2 个文件用于使用 ls 接受答案,1 个文件用于我。后者是正确的行为。

标签: linux shell unix directory


【解决方案1】:

试试这个代码:

 #!/bin/bash

#set basedir to . if no dir is given
if [ -n "$1" ]; then basedir=$1; else basedir=$(pwd);fi

filelist=($(/bin/ls $basedir))
# Outer for loop
for (( i=0; i<${#filelist[@]} ; i+=1 )) ; do
    # Inner for loop
    for (( j=i+1; j<${#filelist[@]} ; j+=1 )) ; do

    echo "Unique between $basedir/${filelist[i]}" "$basedir${filelist[j]}" > $basedir/unique${filelist[i]}${filelist[j]}.txt

    echo -e "Unique in $basedir/${filelist[i]}"  >> $basedir/unique${filelist[i]}${filelist[j]}.txt

    # Will produce unique lines in 'file i' when comparing 'file i' and 'file j'
    join -v 1 <(sort $basedir/${filelist[i]}) <(sort $basedir/${filelist[j]}) >> $basedir/unique${filelist[i]}${filelist[j]}.txt

    echo -e "Unique in  $basedir/${filelist[j]}" >> $basedir/unique${filelist[i]}${filelist[j]}.txt

    # Will produce unique lines in 'file j' when comparing 'file i' and 'file j'
    join -v 2 <(sort $basedir/${filelist[i]}) <(sort $basedir/${filelist[j]}) >> $basedir/unique${filelist[i]}${filelist[j]}.txt

    done

done

文件夹不应包含目录。但它的工作以太。 唯一的文件将在给脚本的文件夹中创建。

【讨论】:

    【解决方案2】:

    假设您的脚本在当前目录上运行,请使用以下命令:-

    filelist=(*)
    

    它将通过 globbing 获取目录中的所有文件。不要使用ls

    除了我的以外,这里的所有答案都是错误的。 (到目前为止的前 3 个。)

    简单测试:

    mkdir -p /tmp/test && cd test && touch List\ s && filelist=($(/bin/ls)) && shuf -e "${filelist[@]} | wc -l
    
    mkdir -p /tmp/test && cd test && touch List\ s && filelist=(*) && shuf -e "${filelist[@]} | wc -l
    

    在这两种情况下都应该给出 1。但它不会。

    【讨论】:

    • 你知道我为什么不应该使用 ls 吗?
    • @AlexRajKaliamoorthy 如果您使用 ls 如果有空格等,它不会给出正确的结果。
    【解决方案3】:

    如果您从当前目录运行脚本,您可以使用以下代码

    fileArr=( $(ls) ) #list the files and store in array
    echo ${#fileArr[@]}
    echo "${fileArr[@]}"
    for i in "${fileArr[@]}"
    do
        echo $i #read the fil
    done    
    

    已编辑:不使用 ls

    shopt -s nullglob
    fileArr1=(*)
    fileArr2=(file*)
    fileArr3=(dir/*)
    
    echo ${#fileArr1[@]}
    echo "${fileArr1[@]}"
    for i in "${fileArr1[@]}"
    do
        echo $i
    done    
    
    echo ${#fileArr2[@]}
    echo "${fileArr2[@]}"
    for i in "${fileArr2[@]}"
    do
        echo $i
    done    
    
    echo ${#fileArr3[@]}
    echo "${fileArr3[@]}"
    for i in "${fileArr3[@]}"
    do
        echo $i
    done    
    

    【讨论】:

      猜你喜欢
      • 2015-11-27
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2018-06-25
      • 2016-08-01
      • 2022-01-01
      • 1970-01-01
      相关资源
      最近更新 更多