我正在尝试做什么:
find "${TEMPDIR}" -name *.[Tt][Xx][Tt] | /
xargs dos2unix -k | /
dd if=/dev/null of="$_" bs=1 seek=$(echo $(stat --format=%s "$_" ) - $( tail -n1 "$_" | wc -c) | bc )
我无法将xargs dos2unix -k | /
的(编辑 输出)文件名传输到第三行,我收到以下错误:
stat: cannot stat '': No such file or directory
tail: cannot open '' for reading: No such file or directory
dd: failed to open '': No such file or directory
显然,我错误地认为"$_"
足以通过管道传递输出。
如何将xargs dos2unix -k
的输出(文本文件)传输到第三行dd if=/dev/null of="$_" bs=1 seek=$(echo $(stat --format=%s "$_" ) - $( tail -n1 "$_" | wc -c) | bc )
?
第3行的解决方案来自另一个关于从文件中删除最后一行的问题的答案,特别是这个答案被吹捧为大文件的一个很好的解决方案:https://stackoverflow.com/a/17794626/893766
答案 0 :(得分:5)
这有帮助吗?
find "${TEMPDIR}" -iname '*.txt' -exec dos2unix "{}" \; -exec sed -i '$d' "{}" \;
答案 1 :(得分:2)
您可以尝试将dos2unix
替换为显式替换:
find "${TEMPDIR}" -iname '*.txt' -exec cat {} \; |
tr -d '\r' |
...
由于新行的窗口为\r\n
,您可以使用\r
命令删除tr
的所有匹配项。
关于find
命令,您可以使用选项-iname
进行不区分大小写的搜索,使用-exec
运行命令。
答案 2 :(得分:1)
如果文件非常大,那么您已经通过使用tr
重写文件来提高效率。然后,您正在使用tail
第二次阅读它,以获取最后一行的索引。
我能想到的最低效的解决方法是用一个执行两个函数的命令替换dos2unix
和dd
,因此您只需读取和写入一次输出文件。
find "$TMPDIR" -iname '*.txt' -exec perl -i -ne '
print $line if defined $line; ($line = $_) =~ s/\015$//' {} \;
您尝试将$_
用于当前文件名并不起作用。 $_
的值是前一个已完成命令使用的最后一个文件名;但是在管道中间,还没有完成任何事情。一种可能的解决方法(我只是为了说明而不是推荐的解决方案)将运行xargs
中您可以访问{}
的所有内容,类似于find -exec
中的工作方式
find "$TMPDIR" -iname '*.txt' -print0 |
xargs -r0 sh -c 'dos2unix -k "{}"
if=/dev/null of="{}" bs=1 seek=$(
echo $(stat --format=%s "{}" ) - $( tail -n1 "{}" | wc -c) | bc)
我添加了-print0
和相应的xargs -0
以及xargs -r
作为良好形式的插图;虽然零终止文本格式是GNU find
扩展名,但通常在其他平台上找不到。
(私下,我可能也会用简单的Awk脚本替换seek
计算,而不是在执行减法时花费三个进程。)