4

I'm trying to find the sed command to remove the end of the line (meaning, get the next line to the current), but only if line starts with the string NOTOK.

example input:

   NOTOK something detected
        details are                : some info

output should be:

NOTOK something detected        details are                : some info
2

With awk:

awk '$1 == "NOTOK" {printf "%s", $0; next} 1' file
  • it works. can you add an explanation of how? – Tom Klino Jan 1 '14 at 15:23
  • For lines where NOTOK is the first word, print that line with no newline. Otherwise print the line unchanged. "1" is a very shorthand for 1 {print} – glenn jackman Jan 1 '14 at 15:26
  • 1
    Better to match NOTOK since there is no guarantee that the string will always be followed by FS. – terdon Jan 1 '14 at 17:26
  • So if I understand correctly, next is used to have awk look at the next line, and '1' is used to print it as is? – Tom Klino Jan 2 '14 at 11:02
5
sed '/NOTOK/ { N; s/\n// }'

If your sed implementation doesn't support ; to separate commands (GNU sed does but it isn't standard):

sed -e '/^NOTOK/ {' -e 'N' -e 's/\n//' -e '}'

Sed gets cryptic very quickly; anything that's more complex than one or more s commands is a good candidate for awk.

awk '/^NOTOK/ {printf "%s", $0; next} 1 {print}'

or

awk '/NOTOK/ {getline n; $0 = $0 n} 1'
1

Joining lines with ed:

cat <<-'EOF' | ed -s file
H
$a

.
,g/^[[:space:]]*NOTOK/.,.+1j
,p
q
EOF

(Note: use w instead of ,p for in-place file editing.)

1

Here are some:

  • Perl

    perl -pe 'chomp if /^\s*NOTOK/' file
    

    The -p flag of perl causes it to print each line of the input file, the -n means read files lines by line and apply the script given by -e. chomp() is a function that simply removes the newline (\n) from the end of a line, so we chomp only if the line begins with NOTOK (/^NOTOK/).

  • awk

    awk '{if($1~/NOTOK/){printf "%s", $0}else{print}}' file
    

    or

    awk '$1~/NOTOK/{printf "%s", $0; next}1;' file
    

    $1 is the first field in awk. If it matches NOTOK we print the line with no newline at the end (printf) otherwise, we print the line as is.

  • bash

    while IFS="" read line; do 
      if [ $(expr index "$line" "NOTOK") -gt "0" ]; then printf "$line";       
      else echo "$line"; fi;
    done < file
    

    IFS is the input field separator which needs to be set to blank in order to read whole lines (otherwise it would get only the first word). So, we read each line of the file into $line, then check if that line begins with NOTOK and print if without a new line at the end (printf) or with (echo) accordingly.

  • Safer to use printf "%s", $0 -- there's no way of knowing what will be in $0, including possible printf %-directives. – glenn jackman Jan 1 '14 at 17:22
  • @glennjackman ah, that's why you did it that way, Fair enough, hadn't thought of that. – terdon Jan 1 '14 at 17:23
  • @terdon: -n is not necessary when -p is used. – cuonglm May 16 '14 at 16:39
  • @Gnouc thanks, I know, it was left over from my testing where I was printing explicitly. By the way, you have more than enough rep to edit, please feel free to just delete it if I do something silly like that again. – terdon May 16 '14 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.