将wc行附加到filename

时间:2017-01-25 04:00:50

标签: bash shell awk file-rename wc

标题说明了一切。我设法得到了这条线:

lines=$(wc file.txt | awk {'print $1'});

但是我可以使用辅助将其添加到文件名中。奖励点用于向我展示如何在当前目录中的所有.txt文件上循环。

9 个答案:

答案 0 :(得分:5)

find -name '*.txt' -execdir bash -c \
  'mv -v "$0" "${0%.txt}_$(wc -l < "$0").txt"' {} \;

,其中

  • 为每个(bash)匹配的文件执行\;命令;
  • {}被当前处理的文件名替换,并作为第一个参数($0)传递给脚本;
  • ${0%.txt}从字符串后面删除.txt的最短匹配项(请参阅official Bash-scripting guide);
  • wc -l < "$0"仅打印文件中的行数(例如,请参阅this question的答案)

示例输出:

'./file-a.txt' -> 'file-a_5.txt'
'./file with spaces.txt' -> 'file with spaces_8.txt'

答案 1 :(得分:1)

您可以使用rename命令,它实际上是一个Perl脚本,如下所示:

rename --dry-run 'my $fn=$_; open my $fh,"<$_"; while(<$fh>){}; $_=$fn; s/.txt$/-$..txt/' *txt

示例输出

'tight_layout1.txt' would be renamed to 'tight_layout1-519.txt'
'tight_layout2.txt' would be renamed to 'tight_layout2-1122.txt'
'tight_layout3.txt' would be renamed to 'tight_layout3-921.txt'
'tight_layout4.txt' would be renamed to 'tight_layout4-1122.txt'

如果您喜欢它所说的内容,请移除--dry-run然后再次运行。

脚本在不使用任何外部进程的情况下对文件中的行进行计数,然后根据您的要求重命名它们,也不使用任何外部进程,因此非常有效。

或者,如果您乐意调用外部进程来计算行数,并避免使用上面的Perl方法:

rename --dry-run 's/\.txt$/-`grep -ch "^" "$_"` . ".txt"/e' *txt

答案 2 :(得分:0)

这样可行,但肯定有更优雅的方式。

for i in *.txt; do
  mv "$i" ${i/.txt/}_$(wc $i | awk {'print $1'})_.txt; 
done

结果会在.txt之前很好地排列行号。 喜欢:

file1_1_.txt 
file2_25_.txt

答案 3 :(得分:0)

使用重命名命令

myVBox.getBorder().getStrokes().get(0).getLeftStrokeWidth();

答案 4 :(得分:0)

您可以使用grep -c '^'获取行数,而不是wcawk

for file in *.txt; do
  [[ ! -f $file ]] && continue # skip over entries that are not regular files
  #
  # move file.txt to file.txt.N where N is the number of lines in file
  #
  # this naming convention has the advantage that if we run the loop again,
  # we will not reprocess the files which were processed earlier
  mv "$file" "$file".$(grep -c '^' "$file")
done

答案 5 :(得分:0)

#/bin/bash

files=$(find . -maxdepth 1 -type f -name '*.txt' -printf '%f\n')
for file in $files; do
    lines=$(wc $file | awk {'print $1'});
    extension="${file##*.}"
    filename="${file%.*}"
    mv "$file" "${filename}${lines}.${extension}"
done

您可以相应地调整maxdepth。

答案 6 :(得分:0)

你也可以这样做:

for file in "path_to_file"/'your_filename_pattern'
    do
      lines=$(wc $file | awk {'print $1'})
      mv $file $file'_'$lines
    done

示例:

    for file in /oradata/SCRIPTS_EL/text*
    do
        lines=$(wc $file | awk {'print $1'})
        mv $file $file'_'$lines
    done

答案 7 :(得分:0)

 awk '
  BEGIN{ for ( i=1;i<ARGC;i++ ) Files[ARGV[i]]=0 }

  {Files[FILENAME]++}

  END{for (file in Files) {
        # if( file !~ "_" Files[file] ".txt$") {

           fileF=file;gsub( /\047/, "\047\"\047\"\047", fileF)
           fileT=fileF;sub( /.txt$/, "_" Files[file] ".txt", fileT)

           system( sprintf( "mv \047%s\047 \047%s\047", fileF, fileT))

        #   }
        }
     }' *.txt

awk通过允许对名称进行更多控制来管理第二个循环的另一种方法(比如避免一个已经从上一个循环中计数的内容)

由于@gniourf_gniourf的好评:

  • 可以在里面留空间的文件名
  • 微小的代码现在很重要这么小的任务

答案 8 :(得分:0)

{ linecount[FILENAME] = FNR }
END {
    linecount[FILENAME] = FNR
    for (file in linecount) {
        newname = gensub(/\.[^\.]*$/, "-"linecount[file]"&", 1, file)
        q = "'"; qq = "'\"'\"'"; gsub(q, qq, newname)
        print "mv -i -v '" gensub(q, qq, "g", file) "' '" newname "'"
    }
    close(c)
}

将上述awk脚本保存在文件中,比如wcmv.awk,运行它:

awk -f wcmv.awk *.txt

它将列出需要运行的命令,以便以所需方式重命名文件(除了它将忽略空文件)。要实际执行它们,您可以将输出传递给shell以执行,如下所示。

awk -f wcmv.awk *.txt | sh

与所有不可逆转的批处理操作一样,只有在看起来没问题时才要小心并执行命令。