Add a prefix string to beginning of each line

LinuxScriptingText Processing

Linux Problem Overview


I have a file as below:

line1
line2
line3

And I want to get:

prefixline1
prefixline2
prefixline3

I could write a Ruby script, but it is better if I do not need to.

prefix will contain /. It is a path, /opt/workdir/ for example.

Linux Solutions


Solution 1 - Linux

# If you want to edit the file in-place
sed -i -e 's/^/prefix/' file

# If you want to create a new file
sed -e 's/^/prefix/' file > file.new

If prefix contains /, you can use any other character not in prefix, or escape the /, so the sed command becomes

's#^#/opt/workdir#'
# or
's/^/\/opt\/workdir/'

Solution 2 - Linux

awk '$0="prefix"$0' file > new_file

In awk the default action is '{print $0}' (i.e. print the whole line), so the above is equivalent to:

awk '{print "prefix"$0}' file > new_file

With Perl (in place replacement):

perl -pi 's/^/prefix/' file

Solution 3 - Linux

You can use Vim in Ex mode:

ex -sc '%s/^/prefix/|x' file
  1. % select all lines

  2. s replace

  3. x save and close

Solution 4 - Linux

If your prefix is a bit complicated, just put it in a variable:

prefix=path/to/file/

Then, you pass that variable and let awk deal with it:

awk -v prefix="$prefix" '{print prefix $0}' input_file.txt

Solution 5 - Linux

If you have Perl:

perl -pe 's/^/PREFIX/' input.file

Solution 6 - Linux

Here is a hightly readable oneliner solution using the ts command from moreutils

$ cat file | ts prefix | tr -d ' '

And how it's derived step by step:

# Step 0. create the file

$ cat file
line1
line2
line3
# Step 1. add prefix to the beginning of each line

$ cat file | ts prefix
prefix line1
prefix line2
prefix line3
# Step 2. remove spaces in the middle

$ cat file | ts prefix | tr -d ' '
prefixline1
prefixline2
prefixline3

Solution 7 - Linux

Using & (the whole part of the input that was matched by the pattern”):

cat in.txt | sed -e "s/.*/prefix&/" > out.txt

OR using back references:

cat in.txt | sed -e "s/\(.*\)/prefix\1/" > out.txt

Solution 8 - Linux

Using the shell:

#!/bin/bash
prefix="something"
file="file"
while read -r line
do
 echo "${prefix}$line"
done <$file > newfile
mv newfile $file

Solution 9 - Linux

While I don't think pierr had this concern, I needed a solution that would not delay output from the live "tail" of a file, since I wanted to monitor several alert logs simultaneously, prefixing each line with the name of its respective log.

Unfortunately, sed, cut, etc. introduced too much buffering and kept me from seeing the most current lines. Steven Penny's suggestion to use the -s option of nl was intriguing, and testing proved that it did not introduce the unwanted buffering that concerned me.

There were a couple of problems with using nl, though, related to the desire to strip out the unwanted line numbers (even if you don't care about the aesthetics of it, there may be cases where using the extra columns would be undesirable). First, using "cut" to strip out the numbers re-introduces the buffering problem, so it wrecks the solution. Second, using "-w1" doesn't help, since this does NOT restrict the line number to a single column - it just gets wider as more digits are needed.

It isn't pretty if you want to capture this elsewhere, but since that's exactly what I didn't need to do (everything was being written to log files already, I just wanted to watch several at once in real time), the best way to lose the line numbers and have only my prefix was to start the -s string with a carriage return (CR or ^M or Ctrl-M). So for example:

#!/bin/ksh

# Monitor the widget, framas, and dweezil
# log files until the operator hits <enter>
# to end monitoring.

PGRP=$$

for LOGFILE in widget framas dweezil
do
(
    tail -f $LOGFILE 2>&1 |
    nl -s"^M${LOGFILE}>  "
) &
sleep 1
done

read KILLEM

kill -- -${PGRP}

Solution 10 - Linux

Using ed:

ed infile <<'EOE'
,s/^/prefix/
wq
EOE

This substitutes, for each line (,), the beginning of the line (^) with prefix. wq saves and exits.

If the replacement string contains a slash, we can use a different delimiter for s instead:

ed infile <<'EOE'
,s#^#/opt/workdir/#
wq
EOE

I've quoted the here-doc delimiter EOE ("end of ed") to prevent parameter expansion. In this example, it would work unquoted as well, but it's good practice to prevent surprises if you ever have a $ in your ed script.

Solution 11 - Linux

Here's a wrapped up example using the sed approach from this answer:

$ cat /path/to/some/file | prefix_lines "WOW: "

WOW: some text
WOW: another line
WOW: more text
prefix_lines
function show_help()
{
  IT=$(CAT <<EOF
    Usage: PREFIX {FILE}

    e.g.

    cat /path/to/file | prefix_lines "WOW: "

      WOW: some text
      WOW: another line
      WOW: more text
  )
  echo "$IT"
  exit
}

# Require a prefix
if [ -z "$1" ]
then
  show_help
fi

# Check if input is from stdin or a file
FILE=$2
if [ -z "$2" ]
then
  # If no stdin exists
  if [ -t 0 ]; then
    show_help
  fi
  FILE=/dev/stdin
fi

# Now prefix the output
PREFIX=$1
sed -e "s/^/$PREFIX/" $FILE

Solution 12 - Linux

  1. You can also achieve this using the backreference technique

     sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
    
  2. You can also use with awk like this

     awk '{print "prefix"$0}' foo.txt > tmp && mv tmp foo.txt
    

Solution 13 - Linux

Using Pythonize (pz):

pz '"preix"+s' <filename

Solution 14 - Linux

Simple solution using a for loop on the command line with bash:

for i in $(cat yourfile.txt); do echo "prefix$i"; done

Save the output to a file:

for i in $(cat yourfile.txt); do echo "prefix$i"; done > yourfilewithprefixes.txt

Solution 15 - Linux

You can do it using AWK

echo example| awk '{print "prefix"$0}'

or

awk '{print "prefix"$0}' file.txt > output.txt

For suffix: awk '{print $0"suffix"}'

For prefix and suffix: awk '{print "prefix"$0"suffix"}'

Solution 16 - Linux

For people on BSD/OSX systems there's utility called lam, short for laminate. lam -s prefix file will do what you want. I use it in pipelines, eg:

find -type f -exec lam -s "{}: " "{}" \; | fzf

...which will find all files, exec lam on each of them, giving each file a prefix of its own filename. (And pump the output to fzf for searching.)

Solution 17 - Linux

If you need to prepend a text at the beginning of each line that has a certain string, try following. In the following example, I am adding # at the beginning of each line that has the word "rock" in it.

sed -i -e 's/^.*rock.*/#&/' file_name

Solution 18 - Linux

SETLOCAL ENABLEDELAYEDEXPANSION

YourPrefix=blabla

YourPath=C:\path

for /f "tokens=*" %%a in (!YourPath!\longfile.csv)     do (echo !YourPrefix!%%a) >> !YourPath!\Archive\output.csv

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpierrotlefouView Question on Stackoverflow
Solution 1 - LinuxAlok SinghalView Answer on Stackoverflow
Solution 2 - LinuxVijayView Answer on Stackoverflow
Solution 3 - LinuxZomboView Answer on Stackoverflow
Solution 4 - LinuxMelkaView Answer on Stackoverflow
Solution 5 - LinuxMajid AzimiView Answer on Stackoverflow
Solution 6 - LinuxnavigaidView Answer on Stackoverflow
Solution 7 - LinuxArk25View Answer on Stackoverflow
Solution 8 - Linuxghostdog74View Answer on Stackoverflow
Solution 9 - LinuxScriptGuyView Answer on Stackoverflow
Solution 10 - LinuxBenjamin W.View Answer on Stackoverflow
Solution 11 - LinuxBrad ParksView Answer on Stackoverflow
Solution 12 - Linuxk_vishwanathView Answer on Stackoverflow
Solution 13 - LinuxHans GinzelView Answer on Stackoverflow
Solution 14 - LinuxMichaelView Answer on Stackoverflow
Solution 15 - LinuxRaufView Answer on Stackoverflow
Solution 16 - LinuxRayView Answer on Stackoverflow
Solution 17 - LinuxmandroidView Answer on Stackoverflow
Solution 18 - LinuxpietervnkView Answer on Stackoverflow