-4

i am wanting to check that the first line of a file to see if it contains only "X", if it contains somthing other then "X" on the first line then i want to echo "yes" if not echo "no" for example:

the first line in a file is XXXXXXX i need the output to be yes

additionally how can i do this with the last line as well ?

  • I think if it contains something other than "X" on the first line then I want to echo "yes"; if not echo "no" and the first line in a file is XXXXXXX I need the output to be yes conflict with each other. Additionally: I wouldn't say an empty line "contains only X" and I wouldn't say and empty line "contains something other than X". What should the output be in case of an empty line? – Kamil Maciorowski Apr 16 '21 at 05:59
  • 2
    You have three other questions on the same topic. You have not accepted any answers on those questions and you have not proven that you have learnt anything from the answers. Question 1, Question 2, Question 3. – Kusalananda Apr 16 '21 at 06:45

5 Answers5

0

The following script takes a filename as a parameter and checks if the first and the last line are composed of only X characters

#!/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

nobody
  • 1,710
0

Because of the title ("… if a line only has a certain characters") I assume "only X" means "only X characters", not strictly "only one X character".

With sed. Let me start with checking the last line because it's more general:

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

To check the N-th line replace $ in the first and in the last expression with N. E.g. for N=5:

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

N=1 can be simplified because in this case we don't need the first expression and the last one can be just q:

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

Notes:

  • If there is no N-th line then there will be no output.

  • Thanks to q sed exits as soon as possible (lines after N-th are not processed).

  • You can use ^XX*$ instead of ^X*$. These will generate different output if the line in question happens to be empty. To test for a line being exactly X use ^X$.

  • In the general case N appears twice and ^X*$ appears twice. It's not DRY but you can use shell variables:

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

In a similar way as in my previous answers to your questions (here and here): Delete all other lines and replace the current line with the string yes or no depending on whether it contains any other character than a single X.

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

The pattern ^X$ matches a lone X on a line, so the first substitution would replace the whole line with the string no if there is only a single X character on it. The t command by itself skips the rest of the script if the most recent s/// command made a change.

To look at the last line, use $ in place of 1 in the sed code:

sed '$!d; s/^X$/no/; t; s/.*/yes/' file
Kusalananda
  • 333,661
0

Using AWK checking the first line:

awk '{ print $0!="X"?"yes":"no"; exit }' infile

same for checking the last line:

awk 'END{ print $0!="X"?"yes":"no" }' infile

and checking on Nth line (replace N in NR==N with the line-number you want verify it is only X or not; NR==line#):

awk 'NR==N{ print $0!="X"?"yes":"no"; exit }' infile
αғsнιη
  • 41,407
0

If you want to also consider lines that may contain NUL characters (or more generally non-text, which also includes sequence of bytes not forming valid characters or lines longer than LINE_MAX or lines not delimited by a newline character), you may need to switch to zsh as other shells can't cope with that easily, and text utilities are not guaranteed to either:

#! /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

Or resort to 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"'