如何打印具有基于分隔符的值的第一个字段

如何打印具有基于分隔符的值的第一个字段

文件 ( 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,例如在单行中使用awkorsed或或其他内容?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

或者使用sedand 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

相关内容