bash - 删除空格分隔文本文件中某些索引处的条目
问题描述
我有一个 .txt 文件,其中包含某些“离群”数据点的数字索引,每个数据点都在自己的行上,由 $outlier_file 调用:
1
7
30
43
48
49
56
57
65
使用以下代码,我可以通过使用 while + read 成功删除某些文件(在本例中为大量神经影像数据)。
while read outlier; do
# Remove current outlier vol from eddy unwarped DWI data
rm $DWI_path/$1/vol000*"$outlier".nii.gz;
done < $outlier_file
但是,我还需要从存储在 $bvec_file 中的另一个文本文件中删除位于这些“异常值”索引处的数字,该文件有 69 列和 3 行。在每一行中,数字以空格分隔。例如,对于这个例子,我需要删除第 1、7、30 等列的所有 3 行,然后将删除异常值的版本保存到一个新的 *.txt 文件中。
0 0.9988864166 -0.0415925034 -0.06652866169 -0.6187155495 0.2291534462 0.8892356214 0.7797364286 0.1957395685 0.9236669465 -0.5400265342 -0.3845263463 -0.4903989539 0.4863306385 -0.6496130843 0.5571164636 0.8110081715 0.9032142094 -0.3234596075 -0.1551409525 -0.806059879 0.4811597826 -0.7820757748 -0.9528881463 0.1916556621 -0.007136403284 -0.2459431735 -0.7915263574 -0.1938049261 -0.1578786349 0.8688043633 -0.5546072294 -0.4019951732 0.2806154851 0.3478762022 0.9548067252 -0.9696777541 -0.4816255837 -0.7962240023 0.6818610905 0.7097978218 0.6739686799 0.1317547111 -0.7648252249 -0.1456021218 -0.5948047487 0.0934205064 0.5268769564 -0.8618324858 -0.3721029232 -0.1827616535 0.691353613 0.4159071597 0.4605505287 0.1312199424 0.426674893 -0.4068291509 0.7167859082 0.2330824665 0.01909161256 -0.06375254731 -0.5981122948 -0.2672253674 0.6875472994 0.2302943724 0 0 0 0
0 0.04258194557 0.9988207007 0.6287131425 0.7469024143 0.5528476637 0.3024964957 0.1446931241 0.9305823612 0.1675139932 0.8208211337 0.8238722992 0.5983722761 0.4238174961 0.639429196 0.1072148887 0.5551578885 0.003337599176 0.511740508 0.9516619405 0.3851404227 0.8526321065 0.1390947346 0.2030449535 0.7759459569 0.165587903 0.9523372297 0.5801228933 0.3277276562 0.7413928896 0.442482978 0.2320585706 0.1079269171 0.1868672655 0.1606136006 0.2968573235 0.1682337977 0.8745679247 0.5989061899 0.4172933119 0.01746934331 0.5641480832 0.7455469091 0.3471016571 0.8035001467 0.5870623128 0.361107261 0.8192579877 0.4160218909 0.5651330299 0.4070513153 0.7221181184 0.714223583 0.6971767133 0.4937978446 0.4232911691 0.8011701162 0.2870385494 0.9016941521 0.09688949547 0.9086826131 0.2631932421 0.152678096 0.6295753848 0.9712458578 0 0 0 0
0 -0.02031513434 -0.02504539005 -0.7747862425 0.2435730944 0.8011542666 0.343155766 -0.6091592581 -0.3093581909 -0.3446424728 -0.1860752773 -0.4163819443 -0.6336083058 0.7641081337 -0.4112580017 -0.8234841915 0.1845683194 0.4291770641 -0.7959243273 -0.2650864686 0.449371034 -0.203724703 0.6074620459 0.2253373638 -0.6009791836 -0.9861692137 0.1804598471 0.1922068008 -0.9246806119 0.6522353256 -0.2222336438 0.7990992685 -0.9092588527 -0.9414539684 0.9236803664 0.0148272357 -0.1772637652 0.05628269894 -0.08566629406 -0.6007759525 0.7041888058 0.4769729119 0.6532997034 -0.5427364139 -0.5772239915 0.5491494803 0.9278330427 0.2263117816 -0.290121617 0.7363179158 0.8949343019 -0.02399176716 0.5629439653 -0.5493977074 -0.8596191107 -0.7992328333 0.4388809483 0.6354737076 0.3641705918 0.9951120218 0.412591228 -0.75696169 0.9514620339 -0.3618197699 0.06038199928 0 0 0 0
据我所知,一种方法是使用 awk 来索引正确的列..(现在只是打印它们)但是如果我调用 $1 (即第一个异常值列的数字索引),我只能让它工作)...
awk -F ' ' '{print $1}' $bvec_file
如果我尝试引用 $outlier 中的值,它就不起作用。相反,这会打印 $bvec_file 的全部内容
while read outlier; do
# Remove current outlier vol from eddy unwarped DWI data
rm $DWI_path/$1/vol000*"$outlier".nii.gz;
# Remove outlier #'s from bvec file
awk -F ' ' '{print $1}' $bvec_file
done < $outlier_file
我完全坚持如何完成这项工作。任何建议将不胜感激。
解决方案
要在循环后从 bvec_file 中删除异常值,并且仅删除成功删除关联文件的异常值:
#!/usr/bin/env bash
tmp=$(mktemp) || exit 1
while IFS= read -r outlier; do
# Remove current outlier vol from eddy unwarped DWI data
rm "$DWI_path/$1"/vol000*"$outlier".nii.gz &&
echo "$outlier"
done < "$outlier_file" |
awk '
NR==FNR { os[$0]; next }
{
for (o in os) {
$o=""
}
$0=$0; $1=$1
}
1' - "$bvec_file" > "$tmp" &&
mv "$tmp" "$bvec_file"
或者在删除文件时一次删除一个异常值:
#!/usr/bin/env bash
tmp=$(mktemp) || exit 1
while IFS= read -r outlier; do
# Remove current outlier vol from eddy unwarped DWI data
rm "$DWI_path/$1"/vol000*"$outlier".nii.gz &&
# Remove outlier #'s from bvec file
awk -v o="$outlier" '{$o=""; $0=$0; $1=$1} 1' "$bvec_file" > "$tmp" &&
mv "$tmp" "$bvec_file"
done < <(sort -rnu "$outlier_file")
始终引用您的 shell 变量,请参阅https://mywiki.wooledge.org/Quotes,&&
每行末尾的 是为了确保下一个命令仅在前面的命令成功时运行。
awk 脚本中的神奇咒语执行以下操作 - 假设您的输入是a b c
并且异常值字段是字段编号 2 b
,:
$ echo 'a b c'
a b c
$
$ echo 'a b c' | awk -v o=2 '{$o=""; print NF ":", $0}'
3: a c
$
$ echo 'a b c' | awk -v o=2 '{$o=""; $0=$0; print NF ":", $0}'
2: a c
$
$ echo 'a b c' | awk -v o=2 '{$o=""; $0=$0; $1=$1; print NF ":", $0}'
2: a c
将o=""
字段值设置为 null,$0=$0
强制 awk 重新拆分$0
为字段,因此它有效地删除字段 2(与将其设置为 null 但它仍然存在的上一步相反),并且从它的字段中$1=$1
重新组合$0
替换每个FS
(任何连续的空白字符链,包括现在a
和c
)之间的 2 个空格和OFS
(单个空白字符)。
推荐阅读
- mongodb - 错误:当我启动和停止服务器时,MongoDB 不时为两个不同的数据库提供服务
- tomcat - 如何解决现场虚拟主机上tomcat默认页面的问题?
- lambda - 添加了 VPC 端点,但 Lambda 仍然超时
- jquery - 如果已加载值,如何在加载时清除文本框?
- java - 为地点消息和发件人显示“null”
- python - Python sys.stdin 和子进程 stdout 的区别
- javascript - 在 node.js 项目中找不到 .env 文件
- android - 对于以下 android API 28 级别,“ApnSetting.Builder”的替代方法是什么?
- wordpress - 我在 WordPress 中有一个电子商务网站,需要从印度进行国际运输?
- ssl - erlang:接收来自 ssl 的响应