我有大约 50 个数据文本文件,我需要从中删除几列。
我一直在使用cut
命令单独删除和重命名它们,但我将拥有更多文件,并且需要一种方法来大规模地执行此操作。
目前我一直在使用:
cut -f1,6,7,8 filename.txt >> filename_Fixed.txt
我能够使用以下方法从所有文件中删除列:
cut -f1,6,7,8 *.txt
但我只能在终端中获取所有输出,或者我可以将其写入单个文本文件。
我想要的是使用 cut 编辑多个文件以删除所需的列:
filename1.txt
filename2.txt
filename3.txt
filename4.txt
.
.
.
并获取编辑后的输出以写入单个文件:
filename_Fixed1.txt
filename_Fixed2.txt
filename_Fixed3.txt
filename_Fixed4.txt
.
.
.
但是一直无法找到将输出写入新文本文件的方法。我是使用命令行的新手,对编码人员不多,所以也许我不知道要搜索什么术语?我什至无法找到任何对我有帮助的谷歌搜索。看起来应该很简单,但我正在挣扎。
无奈之下,我确实尝试了这段代码,知道它不起作用:
cut -f1,6,7,8 *.txt >> ( FILENAME ".fixed" )
我发现">>"
后的部分嵌套在输出多个文件的awk
命令中。
我也尝试(再次知道它不起作用(对输出文件进行通配符,但得到了一个模棱两可的重定向错误。
你试过for
吗?
for f in *.txt ; do
cut -f 1,6,7,8 "$f" > $(basename "$f" .txt)_fixed.txt
done
(注我现在不能尝试basename
,你可以用"${f}_fixed"
替换它(
您还可以在awk
本身中处理所有内容,这将使该过程更加高效,特别是对于大量文件,例如:
awk '
NF < 8 {
print "contains less than 8 fields: ", FILENAME
next
}
{ fn=FILENAME
idx=match(fn, /[0-9]+.*$/)
if (idx == 0) {
print "no numeric suffix for file: ", fn
next;
}
newfn=substr(fn,1,idx-1) "_Fixed" substr(fn,idx)
print $1,$6,$7,$8 > newfn
}
' *.txt
它包含两个规则({...}
之间的表达式(。第一个:
NF < 8 {
print "contains less than 8 fields: ", FILENAME
next
}
只需检查文件是否包含至少 8 个字段(因为您希望字段 8 作为最后一个字段(。如果文件包含的字段少于 8 个,则只需跳到列表中的next
文件。
第二条规则:
{ fn=FILENAME
idx=match(fn, /[0-9]+.*$/)
if (idx == 0) {
print "no numeric suffix for file: ", fn
next;
}
newfn=substr(fn,1,idx-1) "_Fixed" substr(fn,idx)
print $1,$6,$7,$8 > newfn
}
fn=FILENAME
将当前文件名存储为fn
以减少键入,idx=match(fn, /[0-9]+.*$/)
定位文件名的数字后缀开始的索引(例如,"3.txt"
开头(,if (idx == 0)
然后找不到数字后缀,警告并转到next
文件,newfn=substr(fn,1,idx-1) "_Fixed" substr(fn,idx)
从非数字前缀形成新文件名(例如"filename"
(,使用字符串连接添加"_Fixed"
,然后添加数字后缀,最后print $1,$6,$7,$8 > newfn
打印字段(列(1,6,7,8
将输出重定向到新文件名。
有关上面使用的每个字符串函数的更多信息,请参阅 GNU awk 用户指南 - 9.1.3 字符串操作函数
如果我了解您在尝试什么,这应该能够处理尽可能多的文件 - 只要文件有一个数字后缀,可以在文件名中放置"_Fixed"
并且每个文件至少有 8 个字段(列(。您只需在命令行复制/鼠标中键粘贴整个命令即可进行测试。