文件 ( myfile.txt
) 包含数据如下:
abc#ab1=23
nrt#
#clb1aX
amd#322
期望的输出:
abc
nrt
clb1ax
amd
我可以这样做,
for i in `cat myfile.txt`
do
s1=`echo $i | cut -d'#' -f1`;
s2=`echo $i | cut -d'#' -f2`;
if [ "$s1" == "" ]; then
echo "$s2"
else
echo "$s1"
fi;
done;
for
但是,是否有办法在不使用and 的情况下执行此操作if
,例如在单行中使用awk
orsed
或或其他内容?cut
答案1
短的awk
解决方案:
awk -F'#' 'NF{ print ($1 != "" ? $1 : $2) }' file
输出:
abc
nrt
clb1aX
amd
答案2
回答
sed -i "/^#/ { s/#\(.*\)/\1/; b }
s/#.*//" myfile.txt
可以通过在;
后面添加 来将其连接为一行}
,但这样阅读起来会比较困难。
解释
sed -i
将更改保留在文件中,不要将其写入stdout
.
/^#/
- 当sed
位于以 开头的行上时#
。
s/#\(.*\)/\1/
- 将第一次出现的 替换#[everything]
为[everything]
。
b
- 停止当前行的工作并开始下一行的工作。
(阻止s/#.*//
执行命令。)
s/#.*//
- 删除第一次出现的#[everything]
.
(这适用于所有行,除非上一个b
命令提前退出。)
myfile.txt
将执行的文件sed
。
答案3
如果您没有具有值的字段或者它不仅仅在第二列中怎么办?那么你会需要。
awk -F'#' '{for(i=1; i<=NF; i++) if ($i != "") {print $i; break} }' infile
给出以下示例:
abc#asd=123 诺特# #clsdX #### ###这里 acn#123
将给出输出:
abc
nrt
clsdX
here
acn
或者使用sed
and cut
:
cut -d'#' -f1 <(sed 's/^#\+//; /^$/d' infile )
- 删除
s/^#\+//
前导哈希值#
(出现一次或多次) - 删除
/^$/d
上面之后生成的空行,其中一行全部是哈希值#####
,或者删除文件中的空行(如果有)。 - 当文件由哈希分隔时打印
cut -d'#' -f1
第一个字段-f1
-d'#'
或者sed
仅:
sed 's/^#\+//; /^$/d; s/^\([^#]*\)#.*/\1/' infile
- 这
s/^\([^#]*\)#.*/\1/
捕获了一组匹配,从请求行开始直到看到第一个哈希,然后将其打印在结果中并忽略其余部分。
答案4
另一个 sed
sed 's/^#*\([^#]*\).*/\1/' infile
如果您只想使用####删除行
sed 's/^#*\([^#]*\).*/\1/;/^$/d' infile