Append wc lines to filename

2019-06-26 06:44发布

Title says it all. I've managed to get just the lines with this:

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

But I could use an assist appending this to the filename. Bonus points for showing me how to loop this over all the .txt files in the current directory.

9条回答
乱世女痞
2楼-- · 2019-06-26 07:25
find -name '*.txt' -execdir bash -c \
  'mv -v "$0" "${0%.txt}_$(wc -l < "$0").txt"' {} \;

where

  • the bash command is executed for each (\;) matched file;
  • {} is replaced by the currently processed filename and passed as the first argument ($0) to the script;
  • ${0%.txt} deletes shortest match of .txt from back of the string (see the official Bash-scripting guide);
  • wc -l < "$0" prints only the number of lines in the file (see answers to this question, for example)

Sample output:

'./file-a.txt' -> 'file-a_5.txt'
'./file with spaces.txt' -> 'file with spaces_8.txt'
查看更多
相关推荐>>
3楼-- · 2019-06-26 07:32

You could use grep -c '^' to get the number of lines, instead of wc and awk:

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
查看更多
Lonely孤独者°
4楼-- · 2019-06-26 07:33

You could use the rename command, which is actually a Perl script, as follows:

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

Sample Output

'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'

If you like what it says, remove the --dry-run and run again.

The script counts the lines in the file without using any external processes and then renames them as you ask, also without using any external processes, so it quite efficient.

Or, if you are happy to invoke an external process to count the lines, and avoid the Perl method above:

rename --dry-run 's/\.txt$/-`grep -ch "^" "$_"` . ".txt"/e' *txt
查看更多
登录 后发表回答