Using sed, how do you print the first 'N' characters of a line? - shell

Using sed what is an one liner to print the first n characters? I am doing the following:
grep -G 'defn -test.*' OctaneFullTest.clj | sed ....

Don't use sed, use cut:
grep .... | cut -c 1-N
If you MUST use sed:
grep ... | sed -e 's/^\(.\{12\}\).*/\1/'

colrm x
For example, if you need the first 100 characters:
cat file |colrm 101
It's been around for years and is in most linux's and bsd's (freebsd for sure), usually by default. I can't remember ever having to type apt-get install colrm.

don't have to use grep either
an example:
sed -n '/searchwords/{s/^\(.\{12\}\).*/\1/g;p}' file

How about head ?
echo alonglineoftext | head -c 9

To print the N first characters you can remove the N+1 characters up to the end of line:
$ sed 's/.//5g' <<< "defn-test"
defn

Strictly with sed:
grep ... | sed -e 's/^\(.\{N\}\).*$/\1/'

Related

Deleting the nth character of a string in UNIX [duplicate]

I need to cut letter X out of a word:
For example: I need to cut the first letter out of Star Wars, the fourth out of munich,...
1 star wars
4 munich
5 casino royale
7 the fast and the furious
52 a fish called wanda
to
tar wars
munch
casio royale
the fat and the furious
a fish called wanda
I already tried it with cut, but it didn't work.
This was my command:
sed 's/^\([0-9]*\) \(.*\)/ echo \2 | cut -c \1/'
So it gave me this output:
echo star wars | cut -c 5
echo munich | cut -c 5
echo casino royale | cut -c 5
echo the fast and the furious | cut -c 5
echo a fish called wanda | cut -c 52
And than if I send it to bash. I only get the X th letter of the word.
I need to do the exercise with sed and other commands. But I can't use awk or perl.
Thanks
You can use just bash and its parameter expansion:
while read n s ; do
echo "${s:0:n-1}${s:n}"
done < input.txt
If you need one line, just remove the newlines and add a semicolon:
while read n s ; do echo "${s:0:n-1}${s:n}" ; done < input.txt
If you really need to use sed and cut, it's also doable, but a bit less readable:
cat -n input.txt \
| sed 's/\t\([0-9]\+\).*/s=\\(.\\{\1\\}\\).=\\1=/' \
| sed -f- <(sed 's/[0-9]*//' input.txt) \
| cut -c2-
Explanation:
number the lines
turn each line into a sed command that searches for the given number of characters and removes the one following them
run the generated sed command on the original file with the numbers removed
remove the extra leading space
This might work for you (GNU sed):
sed 's/^\([0-9]*\) \(.*\)/echo '\''\2'\''|sed '\''s\/.\/\/\1'\''/e' file
This uses the e flag of the s command to evaluate the RHS and runs a second sed invocation using the backreferences from the LHS. Perhaps easier on the eye is this:
sed -r 's/^([0-9]*) (.*)/echo "\2"|sed "s#.##\1"/e' file
you can use sed in this way:
sed -e '1s/\([a-z]\)\{1\}//' -e 's/^[0-9]\+\s\+\(.*\)/\1/g' file.txt
The first sed regular expresion works on the first line and replace the first character and the second regular expresion works with rest of text, 1 column: one number or more, 2 column; one space or more, after this I put the remaining test in one match \(.*\) and replaced all with this match.

Finding lines without letters or numbers, only with commas, BASH

Good day to all,
I was wondering how to find the line number of a line with only commas. The only but is that I don't know how many commas have each line:
Input:
...
Total,Total,,,
,,,,
,,,,
Alemania,,1.00,,
...
Thanks in advance for any clue
You can do this with a single command:
egrep -n '^[,]+$' file
Line numbers will be prefixed.
Result with your provided four test lines:
2:,,,,
3:,,,,
Now, if you only want the line numbers, you can cut them easily:
egrep -n '^[,]+$' file | cut -d: -f1
sed
sed -n '/^,\+$/=' file
awk
awk '/^,+$/&&$0=NR' file
With GNU sed:
sed -nr '/^,+$/=' file
Output:
2
3

How to pass output of grep to sed?

I have a command like this :
cat error | grep -o [0-9]
which is printing only numbers like 2,30 and so on. Now I wish to pass this number to sed.
Something like :
cat error | grep -o [0-9] | sed -n '$OutPutFromGrep,$OutPutFromGrepp'
Is it possible to do so?
I'm new to shell scripting. Thanks in advance
If the intention is to print the lines that grep returns, generating a sed script might be the way to go:
grep -E -o '[0-9]+' error | sed 's/$/p/' | sed -f - error
You are probably looking for xargs, particularly the -I option:
themel#eristoteles:~$ xargs -I FOO echo once FOO, twice FOO
hi
once hi, twice hi
there
once there, twice there
Your example:
themel#eristoteles:~$ cat error
error in line 123
error in line 234
errors in line 345 and 346
themel#eristoteles:~$ grep -o '[0-9]*' < error | xargs -I OutPutFromGrep echo sed -n 'OutPutFromGrep,OutPutFromGrepp'
sed -n 123,123p
sed -n 234,234p
sed -n 345,345p
sed -n 346,346p
For real-world use, you'll probably want to pass sed an input file and remove the echo.
(Fixed your UUOC, by the way. )
Yes you can pass output from grep to sed.
Please note that in order to match whole numbers you need to use [0-9]* not only [0-9] which would match only a single digit.
Also note you should use double quotes to get variables expanded(in the sed argument) and it seems you have a typo in the second variable name.
Hope this helps.

Output specific line huge text file

I have a sql dump with 300mb that gives me an error on specific line.
But that line is in the middle of the file. What is the best approach?
head -n middleLine dump.sql > output?
Or can i output only the line i need?
You could use sed -n -e 123456p your.dump to print line 123456
If the file is long, consider using
sed -n 'X{p;q}' file
Where X is the line number. It will stop reading the file after reaching that line.
If sed is too slow for your taste you may also use
cat $THE_FILE | head -n $DESIRED_LINE | tail -n 1
You can use sed:
sed -n "x p" dump.sql
where x is the line number.
This might work for you:
sed 'X!d;q' file
where X is the line number.
This can also be done with Perl:
perl -wnl -e '$. == 4444444 and print and exit;' FILENAME.sql
4444444 being the line number you wish to print.
You can also try awk like:
awk 'NR==YOUR_LINE_NO{print}' file_name
If you know a phrase on that line I would use grep. If the phrase is "errortext" use:
$ cat dump.sql | grep "errortext"

How to remove the last character from a bash grep output

COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2`
outputs something like this
"Abc Inc";
What I want to do is I want to remove the trailing ";" as well. How can i do that? I am a beginner to bash. Any thoughts or suggestions would be helpful.
This will remove the last character contained in your COMPANY_NAME var regardless if it is or not a semicolon:
echo "$COMPANY_NAME" | rev | cut -c 2- | rev
I'd use sed 's/;$//'. eg:
COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2 | sed 's/;$//'`
foo="hello world"
echo ${foo%?}
hello worl
I'd use head --bytes -1, or head -c-1 for short.
COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2 | head --bytes -1`
head outputs only the beginning of a stream or file. Typically it counts lines, but it can be made to count characters/bytes instead. head --bytes 10 will output the first ten characters, but head --bytes -10 will output everything except the last ten.
NB: you may have issues if the final character is multi-byte, but a semi-colon isn't
I'd recommend this solution over sed or cut because
It's exactly what head was designed to do, thus less command-line options and an easier-to-read command
It saves you having to think about regular expressions, which are cool/powerful but often overkill
It saves your machine having to think about regular expressions, so will be imperceptibly faster
I believe the cleanest way to strip a single character from a string with bash is:
echo ${COMPANY_NAME:: -1}
but I haven't been able to embed the grep piece within the curly braces, so your particular task becomes a two-liner:
COMPANY_NAME=$(grep "company_name" file.txt); COMPANY_NAME=${COMPANY_NAME:: -1}
This will strip any character, semicolon or not, but can get rid of the semicolon specifically, too.
To remove ALL semicolons, wherever they may fall:
echo ${COMPANY_NAME/;/}
To remove only a semicolon at the end:
echo ${COMPANY_NAME%;}
Or, to remove multiple semicolons from the end:
echo ${COMPANY_NAME%%;}
For great detail and more on this approach, The Linux Documentation Project covers a lot of ground at http://tldp.org/LDP/abs/html/string-manipulation.html
Using sed, if you don't know what the last character actually is:
$ grep company_name file.txt | cut -d '=' -f2 | sed 's/.$//'
"Abc Inc"
Don't abuse cats. Did you know that grep can read files, too?
The canonical approach would be this:
grep "company_name" file.txt | cut -d '=' -f 2 | sed -e 's/;$//'
the smarter approach would use a single perl or awk statement, which can do filter and different transformations at once. For example something like this:
COMPANY_NAME=$( perl -ne '/company_name=(.*);/ && print $1' file.txt )
don't have to chain so many tools. Just one awk command does the job
COMPANY_NAME=$(awk -F"=" '/company_name/{gsub(/;$/,"",$2) ;print $2}' file.txt)
In Bash using only one external utility:
IFS='= ' read -r discard COMPANY_NAME <<< $(grep "company_name" file.txt)
COMPANY_NAME=${COMPANY_NAME/%?}
Assuming the quotation marks are actually part of the output, couldn't you just use the -o switch to return everything between the quote marks?
COMPANY_NAME="\"ABC Inc\";" | echo $COMPANY_NAME | grep -o "\"*.*\""
you can strip the beginnings and ends of a string by N characters using this bash construct, as someone said already
$ fred=abcdefg.rpm
$ echo ${fred:1:-4}
bcdefg
HOWEVER, this is not supported in older versions of bash.. as I discovered just now writing a script for a Red hat EL6 install process. This is the sole reason for posting here.
A hacky way to achieve this is to use sed with extended regex like this:
$ fred=abcdefg.rpm
$ echo $fred | sed -re 's/^.(.*)....$/\1/g'
bcdefg
Some refinements to answer above. To remove more than one char you add multiple question marks. For example, to remove last two chars from variable $SRC_IP_MSG, you can use:
SRC_IP_MSG=${SRC_IP_MSG%??}
cat file.txt | grep "company_name" | cut -d '=' -f 2 | cut -d ';' -f 1
I am not finding that sed 's/;$//' works. It doesn't trim anything, though I'm wondering whether it's because the character I'm trying to trim off happens to be a "$". What does work for me is sed 's/.\{1\}$//'.

Resources