Shell 从列中删除单词并删除行

Shell 从列中删除单词并删除行,shell,unix,Shell,Unix,我想grep从文件的特定列中提取一个单词。然后删除这些行并将所有剩余的行放入另一个文件中。 有人能帮我在shell命令上获得以下输出吗 我有一个以下格式的文件: 1234 8976 897561234 1234 678901234 5678 5678 123456789 4567 123456790 1234 1234 087664566 4567 678990000 1223 6586 212134344 8

我想
grep
从文件的特定列中提取一个单词。然后删除这些行并将所有剩余的行放入另一个文件中。 有人能帮我在shell命令上获得以下输出吗

我有一个以下格式的文件:

1234     8976     897561234   1234  678901234
5678     5678     123456789   4567  123456790
1234     1234     087664566   4567  678990000
1223     6586     212134344   8906  123456789
1234     8976     897561234   1234  678901234
5678     5678     123456789   4567  123456790
1223     6586     212134344   8906  123456789
我想在第二列中单独grep单词“1234”,并删除这些行,然后将其余行放在另一个文件中。因此,输出应采用以下格式:

1234     8976     897561234   1234  678901234
5678     5678     123456789   4567  123456790
1234     1234     087664566   4567  678990000
1223     6586     212134344   8906  123456789
1234     8976     897561234   1234  678901234
5678     5678     123456789   4567  123456790
1223     6586     212134344   8906  123456789
输出应为3行,4行中有3行除外

while read value ;do
  grep -v  ${value:0:10} /tmp/lakshmi.txt > /tmp/output.txt
  cp /tmp/output.txt /tmp/no_post1.txt
done < /tmp/priya.txt
读取值时;做
grep-v${value:0:10}/tmp/lakshmi.txt>/tmp/output.txt
cp/tmp/output.txt/tmp/no_post1.txt
完成

你能帮我修改这个脚本吗?

如果对你有好处,你可以使用
awk

awk '$2==1234' <file-name>

然后,您可以使用
sed
grep-v
甚至
awk
进行进一步处理,或者从当前文件中删除此行,或者只打印与其他文件不匹配的行
awk将更加简单和强大。

尝试以下正则表达式

egrep -v "^[[:space:]]*[^[:space:]]+[[:space:]]+1234[[:space:]]+.*$"
我不确定你的意图是什么,但我最好的猜测是你想做以下事情

while read value ;do
  egrep -v "^[[:space:]]*[^[:space:]]+[[:space:]]+${value:0:10}[[:space:]]+.*$" /tmp/lakshmi.txt > /tmp/output.txt
  cp /tmp/output.txt /tmp/no_post1.txt
done < /tmp/priya.txt
读取值时;做
egrep-v“^[:space:]*[^[:space:]+[:space:]+${value:0:10}[:space:]+.*$”/tmp/lakshmi.txt>/tmp/output.txt
cp/tmp/output.txt/tmp/no_post1.txt
完成
对于列数据,
awk
通常是最好的工具

表面上看,如果您的输入数据在
priya.txt
中,并且您希望输出在
lakshmi.txt
中,那么这将完成以下工作:

awk '$2==1234 { next } { print }' priya.txt > lakshmi.txt
第一个模式检测第2列中的
1234
(以及01234和0001234),并执行一个
next
,它跳过脚本的其余部分。脚本的其余部分打印输入数据;人们经常使用
1
来代替
{print}
,这样就不那么冗长(或不那么清晰)地达到同样的效果

如果您希望在另一个文件中(
filtered.out
)包含
1234
的行,则可以使用:

awk '$2==1234 { print > "filtered.out"; next } { print }' priya.txt > lakshmi.txt
如果列必须正好是
1234
,而不是仅仅在数字上等于
1234
,那么您将使用regx匹配:

awk '$2 ~ /^1234$/ { next } { print }' priya.txt > lakshmi.txt

awk
的优点在于它可以自动将数据拆分为字段,这通常使使用
awk
处理列数据变得容易。您也可以使用Perl或Python或其他类似的脚本语言来完成同样的工作。

您没有准确地指定记录布局。当第一个空字段被4个空格替换时,聪明的解决方案将失败。一块地里面能有空间吗? 当字段具有固定偏移量时,可能需要检查偏移量:

grep -v "^.\{9\}1234"
当/tmp/priya.txt的行数超过1行时,while循环将变得丑陋:

cp /tmp/lakshmi.txt /tmp/output.txt
while read value ;do
  grep -v "^.\{9\}${value}" /tmp/output.txt > /tmp/output2.txt
  mv /tmp/output2.txt /tmp/output.txt
done < /tmp/priya.txt
cp/tmp/lakshmi.txt/tmp/output.txt
读值时;做
grep-v“^.{9\}${value}”/tmp/output.txt>/tmp/output2.txt
mv/tmp/output2.txt/tmp/output.txt
完成
您还可以使用grep的-f选项:

echo "1234     8976     897561234   1234  678901234
5678     5678     123456789   4567  123456790
1234     1234     087664566   4567  678990000
1223     6586     212134344   8906  123456789" |grep -vf <(sed 's/^/^.\\{9\\}/' /tmp/priya.txt )
echo“1234 8976 897561234 1234 678901234
5678     5678     123456789   4567  123456790
1234     1234     087664566   4567  678990000

1223 6586 213434344 8906 123456789“| grep-vf Priya.txt文件将包含1234您如何筛选只在第二列中grep“1234”?你有什么模式吗?或者你只想做一次?它总是第二列吗?我假设您想从lakshmi.txt中删除几条记录,并在priya.txt中给出了要删除的键。你能确认这一点吗(对于其他答案)?忽略grep问题你的脚本还有另一个问题:在每个循环中,上一个循环的结果都将被覆盖。它当然可以工作,但与使用
awk
相比感觉很笨拙。您可以使用:
egrep-v'^[[:space:]*([^[:space:]+[:space:]+){3}1234[:space:]'
来获取第4列中的值1234。
{3}
重复'column,space-after-column'项目3次,然后
1234
和一个空格随后拾取第4列中的值1234。当然,
awk
可能是更好的选择。OP似乎对基于
grep
的解决方案感兴趣。