Bash 检查一行是否只包含某些字符

Bash 检查一行是否只包含某些字符

我想检查文件的第一行,看看它是否只包含“X”,如果它在第一行包含除“X”之外的其他内容,那么我想回显“是”,如果不回显“否”例子:

文件中的第一行是XXXXXXX我需要输出为 yes

另外我怎样才能用最后一行来做到这一点?

答案1

以下脚本采用文件名作为参数,并检查第一行和最后一行是否仅由 X 个字符组成

#!/bin/bash

echo First line
if [ "$(head -n 1 $1 | grep '^X\+$')" == "" ]; then
    #echo something else than X found in the first line
    echo no
else
    #echo only X found in the first line
    echo yes
fi

echo Last line
if [ "$(tail -n 1 $1 | grep '^X\+$')" == "" ]; then
    #echo something else than X found in the last line
    echo no
else
    #echo only X found in the last line
    echo yes
fi

答案2

就像我之前回答你的问题一样(这里这里): 删除所有其他行并用字符串yes或替换当前行no取决于它是否包含除一个单一的 X

sed '1!d; s/^X$/no/; t; s/.*/yes/' file

该模式^X$匹配一​​行上的单个字符,因此如果其中只有一个字符X,则第一次替换会将整行替换为字符串。如果最近的命令进行了更改,则该命令本身会跳过脚本的其余部分。noXts///

要查看最后一行,请在代码中使用$代替:1sed

sed '$!d; s/^X$/no/; t; s/.*/yes/' file

答案3

由于标题(“...如果一行仅包含某些字符”),我认为“仅X”意味着“仅X字符”s”,而不是严格意义上的“只有一个X字符”。

sed。让我从检查最后一行开始,因为它更通用:

sed -n -e '$ ! d' -e '/^X*$/ ino' -e '/^X*$/ ! iyes' -e '$ q'

要检查第 N 行,请将$第一个和最后一个表达式替换为 NEg(N=5):

sed -n -e '5 ! d' -e '/^X*$/ ino' -e '/^X*$/ ! iyes' -e '5 q'

N=1 可以简化,因为在这种情况下我们不需要第一个表达式,最后一个表达式可以是q

sed -n -e '/^X*$/ ino' -e '/^X*$/ ! iyes' -e q

笔记:

  • 如果没有第 N 行,则不会有输出。

  • 感谢q sed尽快退出(第 N 行之后的行不被处理)。

  • 您可以使用^XX*$代替^X*$.如果相关行恰好为空,这些将生成不同的输出。要测试线路是否准确,X请使用^X$.

  • 一般情况下N出现两次,^X*$出现两次。它不是干燥但你可以使用 shell 变量:

    N='$'
    pattern='^X*$'
    sed -n -e "$N ! d" -e "/$pattern/ ino" -e "/$pattern/ ! iyes" -e "$N q"
    

答案4

如果您还想考虑可能包含 NUL 字符的行(或更常见的非文本,其中还包括未形成有效字符的字节序列或长度超过LINE_MAX换行符的行或未由换行符分隔的行),您可能需要切换到zsh因为其他 shell 无法轻松应对,并且文本实用程序也不能保证:

#! /bin/zsh -
if IFS= read -r line < file; then
  case $line in
    ("")     print -u2 empty;
    (*[^X]*) print -u2 does not contain only Xes;;
    (*)      print OK, only Xes;;
  esac
else
  print -u2 a full lines could not be read
fi

或者求助于perl

perl -e '
  open FILE, "<", "file" or die "Cannot open: $!\n";;
  $_ = <FILE>;
  die "a line could not be read\n" unless defined $_;
  die "a full line could not be read\n" unless /\n$/;
  chomp;
  die "does not contain only Xes\n" if /[^X]/;
  print "OK, only Xes\n"'

相关内容