How to format text, such that single line will not exceed N characters [duplicate] - linux

This question already has answers here:
vim command to restructure/force text to 80 columns
(6 answers)
Closed 9 years ago.
I want to know what is the best practice to format selected text, such that each column does not exceed N characters.
For example I had this text at the begging (Note the text doesn't exceed 80 columns):
aaaaaaa aaaaa aaaaaa aaaaa aaaaaaa aaaaaaaaaaaaaaa aaaaaaaaa aaaaaaaa
aaaaa aaaaaaa aaaaaa aaaaaaaaa a aaaa aaaaaaaaa aaaaaaa aaaaaaa aaaa
aaaaa aaaaaaa aaaaaaaaa aaaaaaaa aaaaaa aaaaaaaa aaaaa a aaaaaaaaaaaaaa
aaaaaaa aaaa aaaaaaaaaaa aaaaaa aaaaaaaa aaaaaaa aaaaaaaaa aaaaaaaaaa
aaaaaa aaaaaaaaaa aaaaaaaaaaaa aaaaa aaaaa aaaaa aaaaaaaa aaaaa aaa aaaaa
And then suddenly I had to change the first line and and text like:
BBBBBB BB B BBB BB BBB BBB BBB BBBB BBBBBBBBBBBB
Such the text will become similar to this:
aaaaaaa aaaaa BBBBBB BB B BBB BB BBB BBB BBB BBBB BBBBBBBBBBBB aaaaaa aaaaa aaaaaaa aaaaaaaaaaaaaaa aaaaaaaaa aaaaaaaa
aaaaa aaaaaaa aaaaaa aaaaaaaaa a aaaa aaaaaaaaa aaaaaaa aaaaaaa aaaa
aaaaa aaaaaaa aaaaaaaaa aaaaaaaa aaaaaa aaaaaaaa aaaaa a aaaaaaaaaaaaaa
aaaaaaa aaaa aaaaaaaaaaa aaaaaa aaaaaaaa aaaaaaa aaaaaaaaa aaaaaaaaaa
aaaaaa aaaaaaaaaa aaaaaaaaaaaa aaaaa aaaaa aaaaa aaaaaaaa aaaaa aaa aaaaa
So what is the easiest way to format the text to kind force the limit on columns up to 80 characters?
P.S
I don't wan't to format every line manually.

See here.
Basically, :set tw=80, then use the gq command to reformat preexisting text. To auto-wrap the entire file, go to the first line and type gqG (note capital G).

See this question.
Set textwidth to 80, move to the start of the file (can be done with
Ctrl-Home or gg), and type gqG.
gqG formats the text starting from the current position and to the end
of the file. It will automatically join consecutive lines when
possible. You can place a blank line between two lines if you don't
want those two to be joined together.

Related

Why does the negated character class doesn't work as expected?

xyz mnl pqt aaaa ccc
yz mn ats aa cbc ddd eee ggg
I want to match the first two columns with:
[^\s]*\s[^\s]*\s
But this pattern matches up to all columns but the last one. That is:
xyz mnl pqt aaaa
yz mn ats aa cbc ddd eee
I don't understand this in VIM.
Two things:
\s doesn't work in a character class. Use \S instead.
Prefix the regex with ^ to make it start from the beginning of each line.
^\S*\s\S*\s
Which matches:
xyz mnl pqt aaaa ccc
^^^^^^^^
yz mn ats aa cbc ddd eee ggg
^^^^^^

Mainframe Sort - Getting count based on field

My requirement is to get the count based on the field.
For example:
AAA 1234
AAA 111
...
AAA 112
BBB 123
BBB 123
...
BBB 333
CCC 333
Output should be:
AAA 2000
BBB 300
CCC 1
I am using the Sort card:
SORT FIELDS=(1,3,CH,A)
OUTFIL REMOVECC,NODETAIL,
SECTIONS=(1,3,TRAILER3=(1,3,X,COUNT=(M10,LENGTH=10)))
But I need the count to be left justified. Currently the count is displaying with leading spaces.
How can I make these count results left justified?

In AWK, how to split consecutive rows that have the same string as a "record"?

Let's say I have below text.
aaaaaaa
aaaaaaa
bbb
bbb
bbb
ccccccccccccc
ddddd
ddddd
Is there a way to modify the text as the following.
1 aaaaaaa
1 aaaaaaa
2 bbb
2 bbb
2 bbb
3 ccccccccccccc
4 ddddd
4 ddddd
You could use something like this in awk:
$ awk '{print ($0!=p?++i:i),$0;p=$0}' file
1 aaaaaaa
1 aaaaaaa
2 bbb
2 bbb
2 bbb
3 ccccccccccccc
4 ddddd
4 ddddd
i is incremented whenever the current line differs from the previous line. p holds the value of the previous line, $0.
Alternatively, as suggested by JID:
awk '$0!=p{p=$0;i++}{print i,$0}' file
When the current line differs from p, replace p and increment i. See the comments for discussion of the pros and cons of either approach :)
A further contribution (and even shorter!) by NeronLeVelu
$ awk '{print i+=($0!=p),p=$0}' file
This version performs the addition assignment and basic assignment within the print statement. This works because the return value of each assignment is the value that has been assigned.
As pointed out in the comments, if the first line of the file is empty, the behaviour changes slightly. Assuming that the first line should always begin with a 1, the following block can be added to the start of any of the one-liners:
NR==1{p=$0;i=1}
i.e. on the first line, initialise p to the contents of the line (empty or not) and i to 1. Thanks to Wintermute for this suggestion.

How to replace the character I want in a line

1 aaa bbb aaa
2 aaa ccccccccc aaa
3 aaa xx aaa
How to replace the second aaa to yyy for each line
1 aaa bbb yyy
2 aaa ccccccccc yyy
3 aaa xx yyy
Issuing the following command will solve your problem.
:%s/\(aaa.\{-}\)aaa/\1yyy/g
Another way would be with \zs and \ze, which mark the beginning and end of a match in a pattern. So you could do:
:%s/aaa.*\zsaaa\ze/yyy
In other words, find "aaa" followed by anything and then another "aaa", and replace that with "yyy".
If you have three "aaa"s on a line, this won't work, though, and you should use \{-} instead of *. (See :h non-greedy)

Remove trailing letters at the end of string

I have some strings like below:
ffffffffcfdeee^dddcdeffffffffdddcecffffc^cbcb^cb`cdaba`eeeeeefeba[NNZZcccYccaccBBBBBBBBBBBBBBBBBBBBBB
eedeedffcc^bb^bccccbadddba^cc^e`eeedddda`deca_^^\```a```^b^`I^aa^bb^`_b\a^b```Y_\`b^`aba`cM[SS\ZY^BBB
Each string may (or may not) end with a stretch of trailing B of varied length.
I'm just wondering if we can simply use Bash code to remove the B stretch?
You could try something like
sed 's/\(.\)B*$/\1/' file
Input
aaa BBBBB
aaa BBBBB cccc
aaa bbb ccc BBBBBBB
Output
aaa
aaa BBBBB cccc
aaa bbb ccc
just with bash
shopt -s extglob
str="a.zxn;lqwyerpyqgha;lsdnBBBBB"
str=${str%%+(B)}
echo $str # ==> a.zxn;lqwyerpyqgha;lsdn
This might work for you:
sed 's/B*$//' file

Resources