我有两个文件。文件A包含用N行写的文本,文件B包含一个二进制模式字符串0和1,它也有N长度。
我想从文件A中删除与文件B中包含0的行号相同的行。
我读过用awk做这个可能是个好主意,但我不知道如何使用它。
文件非常长,例如2000行(它们是视频轨迹)
例如:
档案A:
Line 1: 123456
Line 2: 789012
Line 3: 345678
Line 4: 901234
档案B:
Line 1: 1
Line 2: 0
Line 3: 0
Line 4: 1
执行后:
档案A:
Line 1: 123456
Line 2: 901234
答案 0 :(得分:6)
您可以使用paste
和cut
:
paste fileB fileA | grep '^1' | cut -f2-
paste fileB fileA
- 并排粘贴文件内容,由选项卡grep '^1'
- 过滤以1 cut -f2-
- 提取我们需要的内容 cut
和paste
都使用制表符作为默认分隔符。
这与Benjamin's解决方案非常相似。这里的一个小优点是,即使fileA每行还有多个字段,它也能正常工作。
答案 1 :(得分:3)
您可以使用decorate – filter – undecorate模式:
paste fileA fileB | grep -v '0$' | cut -f1
这会打印每个文件的行(paste
),然后过滤以0
(grep
)结尾的行,然后从第二个文件中删除行(cut
)。
如果fileA
包含用于paste
和cut
的分隔符(默认情况下为标签符号),则会中断。为了避免这种情况,我们可以交换文件(参见codeforester's answer)或使用类似
paste fileA fileB | sed -n '/1$/s/\t.$//p'
(如果行以1
结尾,请删除标签和最后一个字符,然后打印)或
paste fileA fileB | grep -Po '.*(?=\t1$)'
(仅匹配以1
结尾的行,使用零宽度前瞻以排除制表符和1
匹配);最后一个解决方案需要一个支持Perl兼容正则表达式(PCRE)的grep,例如GNU grep。
答案 2 :(得分:3)
这里有很多有趣的答案。这是一个重击:
while IFS= read -r -u3 line; IFS= read -r -u4 bool; do
((bool == 1)) && printf "%s\n" "$line"
done 3<fileA 4<fileB
这比其他解决方案要慢得多。
答案 3 :(得分:3)
假设输入文件中并不存在Line 1:
等,您只需要:
awk 'NR==FNR{a[NR]=$0;next} a[FNR]' fileB fileA
答案 4 :(得分:2)
单个awk
命令可以从两个文件中读取。
awk '(getline flag < "fileB") > 0 && flag' fileA
从fileA
读取每一行后,从fileB
读取一行到变量标志,并测试其整数值是否为真。对于真值,将打印fileA
的行。
根据您的awk
版本,您可能需要使用int(flag)
或flag+0
强制将值视为整数而不是普通的非空字符串。< / p>
答案 5 :(得分:2)
另一个paste
/ awk
解决方案。如果数据中出现选项卡,则找到另一个分隔符。
paste file2 file1 | awk -F'\t' '$1{print $2}'
答案 6 :(得分:1)
编辑: @ codeforester的评论如果Line 1
或Line 2
不属于您的File1和File2,那么以下内容可能有所帮助。
awk 'FNR==NR{a[FNR]=$0;next} $0!=0{print a[FNR]}' filea fileb
解决方案第二: 首先读取fileb文件然后再读取filea。
awk 'FNR==NR{if($0!=0){a[FNR]=$0};next} a[FNR]' fileb filea
如果OP在他/她的文件中包含字符串line1,line2,则解决方案1的替代方案。
关注awk
也可能有所帮助。
awk '
FNR==NR{
a[FNR]=$NF;
next}
$NF!=0{
printf("%s%s\n","Line " ++count": ",a[FNR])
}' filea fileb
答案 7 :(得分:0)
paste
和sed
组合:
paste -d'\n' fileB fileA | sed -n '/^1$/{n;p}'
123456
901234
您交错文件:
1
123456
0
789012
0
345678
1
901234
然后使用sed
打印直接跟随仅1
的行的行。但是,如果您的条目仅由1
中的fileA
组成,则此操作将无法正常运行。如果是这种情况,则必须使用以下sed
命令,如果我们当前正在处理奇数/偶数行,则需要考虑该命令:
paste -d'\n' fileB fileA | sed -n '1~2{/^1$/{n;p}}'