Replace text in lines in a file with incrementsReplace data at specific positions in txt file using data from...
Is there a familial term for apples and pears?
Could a US political party gain complete control over the government by removing checks & balances?
What is it called when one voice type sings a 'solo'?
Denied boarding due to overcrowding, Sparpreis ticket. What are my rights?
What is the offset in a seaplane's hull?
What does "enim et" mean?
Copycat chess is back
Prime joint compound before latex paint?
How is it possible for user's password to be changed after storage was encrypted? (on OS X, Android)
Does a dangling wire really electrocute me if I'm standing in water?
How to answer pointed "are you quitting" questioning when I don't want them to suspect
When blogging recipes, how can I support both readers who want the narrative/journey and ones who want the printer-friendly recipe?
Patience, young "Padovan"
Re-submission of rejected manuscript without informing co-authors
Shall I use personal or official e-mail account when registering to external websites for work purpose?
Can I legally use front facing blue light in the UK?
What is GPS' 19 year rollover and does it present a cybersecurity issue?
aging parents with no investments
Why is the design of haulage companies so “special”?
How to make payment on the internet without leaving a money trail?
Is a vector space a subspace?
Unbreakable Formation vs. Cry of the Carnarium
What are the advantages and disadvantages of running one shots compared to campaigns?
Are objects structures and/or vice versa?
Replace text in lines in a file with increments
Replace data at specific positions in txt file using data from another fileReplace one block of text with another block of text when replacement text is in a fileReplace matching parentheses with enclosing contentHow can I edit the last n lines in a file?UNIX command for replacing within delimiter based on position of the delimiterUsing sed I want to replace the first block of text that matchessearch and Replace substring in mac address in a text fileText Processing - Get 2 lines with exact text between themReplace the part of lines in multiple files matching a pattern with lines from another file in orderText file: find string, save string field to var, find 2nd string, replace field with var, repeat to end
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I have a file with multiple lines (no. of lines unknown)
DD0TRANSID000019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRANSID000019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRANSID000019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.0
The text TRANSID000 is in every line starting from 3rd to 10th poisition I need to be able to replace it with TRAN000066 in increments of 1
66 is a variable I am getting from another file (say nextcounter) for storing the start of the counter. Once the program updates all the lines, I should be able to capture the last number and update the nextcounter file with it.
Output
DD0TRAN00066019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRAN00067019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRAN00068019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NStatus Report
awk sed perl
New contributor
add a comment |
I have a file with multiple lines (no. of lines unknown)
DD0TRANSID000019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRANSID000019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRANSID000019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.0
The text TRANSID000 is in every line starting from 3rd to 10th poisition I need to be able to replace it with TRAN000066 in increments of 1
66 is a variable I am getting from another file (say nextcounter) for storing the start of the counter. Once the program updates all the lines, I should be able to capture the last number and update the nextcounter file with it.
Output
DD0TRAN00066019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRAN00067019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRAN00068019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NStatus Report
awk sed perl
New contributor
add a comment |
I have a file with multiple lines (no. of lines unknown)
DD0TRANSID000019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRANSID000019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRANSID000019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.0
The text TRANSID000 is in every line starting from 3rd to 10th poisition I need to be able to replace it with TRAN000066 in increments of 1
66 is a variable I am getting from another file (say nextcounter) for storing the start of the counter. Once the program updates all the lines, I should be able to capture the last number and update the nextcounter file with it.
Output
DD0TRAN00066019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRAN00067019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRAN00068019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NStatus Report
awk sed perl
New contributor
I have a file with multiple lines (no. of lines unknown)
DD0TRANSID000019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRANSID000019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRANSID000019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.0
The text TRANSID000 is in every line starting from 3rd to 10th poisition I need to be able to replace it with TRAN000066 in increments of 1
66 is a variable I am getting from another file (say nextcounter) for storing the start of the counter. Once the program updates all the lines, I should be able to capture the last number and update the nextcounter file with it.
Output
DD0TRAN00066019021210504250003379433005533665506656000008587201902070168304000.0AK 0000L00000.00 N 01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment
DD0TRAN00067019021210505110003379433005535567606656000008587201902085381804000.0FC 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact
DD0TRAN00068019021210510360003379433005535568006656000008587201902085381804000.0SR 0000L00000.00 N 53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NStatus Report
awk sed perl
awk sed perl
New contributor
New contributor
New contributor
asked yesterday
Rohit PrasadRohit Prasad
11
11
New contributor
New contributor
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
I think this awk
script should do the job. It does everything from within the script as this the simplest setup. But see further on for an alternative that lets you handle your nextcounter as a shell variable:
BEGIN
{ getline counter < "nextcounter"; }
/TRANSID000/
{
replacement_string = sprintf("TRAN%05d", counter++);
gsub("TRANSID000", replacement_string);
print;
}
END
{ printf("%dn", counter) > "nextcounter"; }
You may invoke it with a one-liner like this:
cat data | awk -- 'BEGIN { getline counter < "nextcounter"; } /TRANSID000/{ replacement_string = sprintf("TRAN%05d", counter++); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "nextcounter"; }'
Please note:
- In your OP you first say that you want a string like
TRAN000066
i.e. having 6 digits in all, but then your sample output has a string likeTRAN00066
i.e. with 5 digits. I followed your sample output but if instead you need 6-digits precision just change theTRAN%05d
string withTRAN%06d
- As per your description I considered the number taken from the
nextcounter
file as being the first number to use in replacement. If instead you want to first increment the number just change thecounter++
piece with++counter
- I considered
nextcounter
as a file containing only one line with only a numeric integer number. If that's not precisely the case then you'll need to modify the script'sBEGIN
andEND
section
If you prefer not to have the awk script update your nextcounter
file directly, and instead handle such nextcounter value as a shell variable, you need a bit more complicated setup which involves using a temporary file to store the updated counter. Something like this:
tempfile=$(mktemp) ; cat data | awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string) ; print; } END { printf("%dn", counter) > tempfile; }' && read nextcounter < "${tempfile}" ; rm "${tempfile}"
Broken down for explanation:
tempfile=$(mktemp) # create temporary file
cat data | pipe data to awk ...
awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- # provide initial counter and tempfile to awk
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string) ;
print;
}
END
{ printf("%dn", counter) > tempfile; }' # write updated counter to temporary file
&& read nextcounter < "${tempfile}" # read updated counter into ${nextcounter} shell variable
rm "${tempfile}"
This expects the initial counter in ${nextcounter}
, and updates that same variable at the end.
IF creating temporary files is not an option, then you might try using file-descriptors over unnamed pipes, but this requires Bash v3+ and a system that allows opening pipes in read/write mode. Linux allows that, MacOS doesn’t, don’t know about other Unix-es.
It would be like:
exec 9<> <(:) ; cat data | awk -v counter="${nextcounter:-0}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "/dev/fd/9"; }' && read nextcounter <&9 ; exec 9<&-
Broken down:
exec 9<> <(:) # open fd 9 onto unnamed pipe R/W
cat data |
awk -v counter="${nextcounter:-0}" --
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string);
print; }
END
{ printf("%dn", counter) > "/dev/fd/9"; }' # write updated counter to fd 9
&& read nextcounter <&9 # read updated counter from fd 9 into ${nextcounter} shell variable
exec 9<&- # close fd 9
add a comment |
if your file in 'file', on bash shell type,
inp=66;i=$inp; while read -r ln;do;echo $ln sed -E "s/TRANSID000/TRAN0000$i/i";let i++;done<file
Would you be able to explain the command a bit? It seem like$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.
– Kusalananda♦
20 hours ago
add a comment |
With perl
:
perl -spe 's/TRANSID000K/$n++/e' -- -n=66 < your-file
Or if you need the number to be padded with 0s to a length of 5 (00001, 00010, 00100...):
perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=66 < your-file
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
@RohitPrasad, in which way did it not work? Note that inbash
and all Bourne-like shells but zsh, parameter expansions need to be quoted:-n="$variable"
(or"-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Checkprintf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Rohit Prasad is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f511081%2freplace-text-in-lines-in-a-file-with-increments%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think this awk
script should do the job. It does everything from within the script as this the simplest setup. But see further on for an alternative that lets you handle your nextcounter as a shell variable:
BEGIN
{ getline counter < "nextcounter"; }
/TRANSID000/
{
replacement_string = sprintf("TRAN%05d", counter++);
gsub("TRANSID000", replacement_string);
print;
}
END
{ printf("%dn", counter) > "nextcounter"; }
You may invoke it with a one-liner like this:
cat data | awk -- 'BEGIN { getline counter < "nextcounter"; } /TRANSID000/{ replacement_string = sprintf("TRAN%05d", counter++); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "nextcounter"; }'
Please note:
- In your OP you first say that you want a string like
TRAN000066
i.e. having 6 digits in all, but then your sample output has a string likeTRAN00066
i.e. with 5 digits. I followed your sample output but if instead you need 6-digits precision just change theTRAN%05d
string withTRAN%06d
- As per your description I considered the number taken from the
nextcounter
file as being the first number to use in replacement. If instead you want to first increment the number just change thecounter++
piece with++counter
- I considered
nextcounter
as a file containing only one line with only a numeric integer number. If that's not precisely the case then you'll need to modify the script'sBEGIN
andEND
section
If you prefer not to have the awk script update your nextcounter
file directly, and instead handle such nextcounter value as a shell variable, you need a bit more complicated setup which involves using a temporary file to store the updated counter. Something like this:
tempfile=$(mktemp) ; cat data | awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string) ; print; } END { printf("%dn", counter) > tempfile; }' && read nextcounter < "${tempfile}" ; rm "${tempfile}"
Broken down for explanation:
tempfile=$(mktemp) # create temporary file
cat data | pipe data to awk ...
awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- # provide initial counter and tempfile to awk
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string) ;
print;
}
END
{ printf("%dn", counter) > tempfile; }' # write updated counter to temporary file
&& read nextcounter < "${tempfile}" # read updated counter into ${nextcounter} shell variable
rm "${tempfile}"
This expects the initial counter in ${nextcounter}
, and updates that same variable at the end.
IF creating temporary files is not an option, then you might try using file-descriptors over unnamed pipes, but this requires Bash v3+ and a system that allows opening pipes in read/write mode. Linux allows that, MacOS doesn’t, don’t know about other Unix-es.
It would be like:
exec 9<> <(:) ; cat data | awk -v counter="${nextcounter:-0}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "/dev/fd/9"; }' && read nextcounter <&9 ; exec 9<&-
Broken down:
exec 9<> <(:) # open fd 9 onto unnamed pipe R/W
cat data |
awk -v counter="${nextcounter:-0}" --
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string);
print; }
END
{ printf("%dn", counter) > "/dev/fd/9"; }' # write updated counter to fd 9
&& read nextcounter <&9 # read updated counter from fd 9 into ${nextcounter} shell variable
exec 9<&- # close fd 9
add a comment |
I think this awk
script should do the job. It does everything from within the script as this the simplest setup. But see further on for an alternative that lets you handle your nextcounter as a shell variable:
BEGIN
{ getline counter < "nextcounter"; }
/TRANSID000/
{
replacement_string = sprintf("TRAN%05d", counter++);
gsub("TRANSID000", replacement_string);
print;
}
END
{ printf("%dn", counter) > "nextcounter"; }
You may invoke it with a one-liner like this:
cat data | awk -- 'BEGIN { getline counter < "nextcounter"; } /TRANSID000/{ replacement_string = sprintf("TRAN%05d", counter++); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "nextcounter"; }'
Please note:
- In your OP you first say that you want a string like
TRAN000066
i.e. having 6 digits in all, but then your sample output has a string likeTRAN00066
i.e. with 5 digits. I followed your sample output but if instead you need 6-digits precision just change theTRAN%05d
string withTRAN%06d
- As per your description I considered the number taken from the
nextcounter
file as being the first number to use in replacement. If instead you want to first increment the number just change thecounter++
piece with++counter
- I considered
nextcounter
as a file containing only one line with only a numeric integer number. If that's not precisely the case then you'll need to modify the script'sBEGIN
andEND
section
If you prefer not to have the awk script update your nextcounter
file directly, and instead handle such nextcounter value as a shell variable, you need a bit more complicated setup which involves using a temporary file to store the updated counter. Something like this:
tempfile=$(mktemp) ; cat data | awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string) ; print; } END { printf("%dn", counter) > tempfile; }' && read nextcounter < "${tempfile}" ; rm "${tempfile}"
Broken down for explanation:
tempfile=$(mktemp) # create temporary file
cat data | pipe data to awk ...
awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- # provide initial counter and tempfile to awk
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string) ;
print;
}
END
{ printf("%dn", counter) > tempfile; }' # write updated counter to temporary file
&& read nextcounter < "${tempfile}" # read updated counter into ${nextcounter} shell variable
rm "${tempfile}"
This expects the initial counter in ${nextcounter}
, and updates that same variable at the end.
IF creating temporary files is not an option, then you might try using file-descriptors over unnamed pipes, but this requires Bash v3+ and a system that allows opening pipes in read/write mode. Linux allows that, MacOS doesn’t, don’t know about other Unix-es.
It would be like:
exec 9<> <(:) ; cat data | awk -v counter="${nextcounter:-0}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "/dev/fd/9"; }' && read nextcounter <&9 ; exec 9<&-
Broken down:
exec 9<> <(:) # open fd 9 onto unnamed pipe R/W
cat data |
awk -v counter="${nextcounter:-0}" --
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string);
print; }
END
{ printf("%dn", counter) > "/dev/fd/9"; }' # write updated counter to fd 9
&& read nextcounter <&9 # read updated counter from fd 9 into ${nextcounter} shell variable
exec 9<&- # close fd 9
add a comment |
I think this awk
script should do the job. It does everything from within the script as this the simplest setup. But see further on for an alternative that lets you handle your nextcounter as a shell variable:
BEGIN
{ getline counter < "nextcounter"; }
/TRANSID000/
{
replacement_string = sprintf("TRAN%05d", counter++);
gsub("TRANSID000", replacement_string);
print;
}
END
{ printf("%dn", counter) > "nextcounter"; }
You may invoke it with a one-liner like this:
cat data | awk -- 'BEGIN { getline counter < "nextcounter"; } /TRANSID000/{ replacement_string = sprintf("TRAN%05d", counter++); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "nextcounter"; }'
Please note:
- In your OP you first say that you want a string like
TRAN000066
i.e. having 6 digits in all, but then your sample output has a string likeTRAN00066
i.e. with 5 digits. I followed your sample output but if instead you need 6-digits precision just change theTRAN%05d
string withTRAN%06d
- As per your description I considered the number taken from the
nextcounter
file as being the first number to use in replacement. If instead you want to first increment the number just change thecounter++
piece with++counter
- I considered
nextcounter
as a file containing only one line with only a numeric integer number. If that's not precisely the case then you'll need to modify the script'sBEGIN
andEND
section
If you prefer not to have the awk script update your nextcounter
file directly, and instead handle such nextcounter value as a shell variable, you need a bit more complicated setup which involves using a temporary file to store the updated counter. Something like this:
tempfile=$(mktemp) ; cat data | awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string) ; print; } END { printf("%dn", counter) > tempfile; }' && read nextcounter < "${tempfile}" ; rm "${tempfile}"
Broken down for explanation:
tempfile=$(mktemp) # create temporary file
cat data | pipe data to awk ...
awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- # provide initial counter and tempfile to awk
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string) ;
print;
}
END
{ printf("%dn", counter) > tempfile; }' # write updated counter to temporary file
&& read nextcounter < "${tempfile}" # read updated counter into ${nextcounter} shell variable
rm "${tempfile}"
This expects the initial counter in ${nextcounter}
, and updates that same variable at the end.
IF creating temporary files is not an option, then you might try using file-descriptors over unnamed pipes, but this requires Bash v3+ and a system that allows opening pipes in read/write mode. Linux allows that, MacOS doesn’t, don’t know about other Unix-es.
It would be like:
exec 9<> <(:) ; cat data | awk -v counter="${nextcounter:-0}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "/dev/fd/9"; }' && read nextcounter <&9 ; exec 9<&-
Broken down:
exec 9<> <(:) # open fd 9 onto unnamed pipe R/W
cat data |
awk -v counter="${nextcounter:-0}" --
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string);
print; }
END
{ printf("%dn", counter) > "/dev/fd/9"; }' # write updated counter to fd 9
&& read nextcounter <&9 # read updated counter from fd 9 into ${nextcounter} shell variable
exec 9<&- # close fd 9
I think this awk
script should do the job. It does everything from within the script as this the simplest setup. But see further on for an alternative that lets you handle your nextcounter as a shell variable:
BEGIN
{ getline counter < "nextcounter"; }
/TRANSID000/
{
replacement_string = sprintf("TRAN%05d", counter++);
gsub("TRANSID000", replacement_string);
print;
}
END
{ printf("%dn", counter) > "nextcounter"; }
You may invoke it with a one-liner like this:
cat data | awk -- 'BEGIN { getline counter < "nextcounter"; } /TRANSID000/{ replacement_string = sprintf("TRAN%05d", counter++); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "nextcounter"; }'
Please note:
- In your OP you first say that you want a string like
TRAN000066
i.e. having 6 digits in all, but then your sample output has a string likeTRAN00066
i.e. with 5 digits. I followed your sample output but if instead you need 6-digits precision just change theTRAN%05d
string withTRAN%06d
- As per your description I considered the number taken from the
nextcounter
file as being the first number to use in replacement. If instead you want to first increment the number just change thecounter++
piece with++counter
- I considered
nextcounter
as a file containing only one line with only a numeric integer number. If that's not precisely the case then you'll need to modify the script'sBEGIN
andEND
section
If you prefer not to have the awk script update your nextcounter
file directly, and instead handle such nextcounter value as a shell variable, you need a bit more complicated setup which involves using a temporary file to store the updated counter. Something like this:
tempfile=$(mktemp) ; cat data | awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string) ; print; } END { printf("%dn", counter) > tempfile; }' && read nextcounter < "${tempfile}" ; rm "${tempfile}"
Broken down for explanation:
tempfile=$(mktemp) # create temporary file
cat data | pipe data to awk ...
awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- # provide initial counter and tempfile to awk
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string) ;
print;
}
END
{ printf("%dn", counter) > tempfile; }' # write updated counter to temporary file
&& read nextcounter < "${tempfile}" # read updated counter into ${nextcounter} shell variable
rm "${tempfile}"
This expects the initial counter in ${nextcounter}
, and updates that same variable at the end.
IF creating temporary files is not an option, then you might try using file-descriptors over unnamed pipes, but this requires Bash v3+ and a system that allows opening pipes in read/write mode. Linux allows that, MacOS doesn’t, don’t know about other Unix-es.
It would be like:
exec 9<> <(:) ; cat data | awk -v counter="${nextcounter:-0}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string); print; } END { printf("%dn", counter) > "/dev/fd/9"; }' && read nextcounter <&9 ; exec 9<&-
Broken down:
exec 9<> <(:) # open fd 9 onto unnamed pipe R/W
cat data |
awk -v counter="${nextcounter:-0}" --
'/TRANSID000/
{ replacement_string = sprintf("TRAN%05d", ++counter);
gsub("TRANSID000", replacement_string);
print; }
END
{ printf("%dn", counter) > "/dev/fd/9"; }' # write updated counter to fd 9
&& read nextcounter <&9 # read updated counter from fd 9 into ${nextcounter} shell variable
exec 9<&- # close fd 9
edited 14 hours ago
answered yesterday
LL3LL3
1,1297
1,1297
add a comment |
add a comment |
if your file in 'file', on bash shell type,
inp=66;i=$inp; while read -r ln;do;echo $ln sed -E "s/TRANSID000/TRAN0000$i/i";let i++;done<file
Would you be able to explain the command a bit? It seem like$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.
– Kusalananda♦
20 hours ago
add a comment |
if your file in 'file', on bash shell type,
inp=66;i=$inp; while read -r ln;do;echo $ln sed -E "s/TRANSID000/TRAN0000$i/i";let i++;done<file
Would you be able to explain the command a bit? It seem like$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.
– Kusalananda♦
20 hours ago
add a comment |
if your file in 'file', on bash shell type,
inp=66;i=$inp; while read -r ln;do;echo $ln sed -E "s/TRANSID000/TRAN0000$i/i";let i++;done<file
if your file in 'file', on bash shell type,
inp=66;i=$inp; while read -r ln;do;echo $ln sed -E "s/TRANSID000/TRAN0000$i/i";let i++;done<file
answered 22 hours ago
abdanabdan
474
474
Would you be able to explain the command a bit? It seem like$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.
– Kusalananda♦
20 hours ago
add a comment |
Would you be able to explain the command a bit? It seem like$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.
– Kusalananda♦
20 hours ago
Would you be able to explain the command a bit? It seem like
$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.– Kusalananda♦
20 hours ago
Would you be able to explain the command a bit? It seem like
$i
is a positive integer, but since it's not zero-filled to a fixed width, the result may be unexpected.– Kusalananda♦
20 hours ago
add a comment |
With perl
:
perl -spe 's/TRANSID000K/$n++/e' -- -n=66 < your-file
Or if you need the number to be padded with 0s to a length of 5 (00001, 00010, 00100...):
perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=66 < your-file
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
@RohitPrasad, in which way did it not work? Note that inbash
and all Bourne-like shells but zsh, parameter expansions need to be quoted:-n="$variable"
(or"-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Checkprintf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
add a comment |
With perl
:
perl -spe 's/TRANSID000K/$n++/e' -- -n=66 < your-file
Or if you need the number to be padded with 0s to a length of 5 (00001, 00010, 00100...):
perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=66 < your-file
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
@RohitPrasad, in which way did it not work? Note that inbash
and all Bourne-like shells but zsh, parameter expansions need to be quoted:-n="$variable"
(or"-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Checkprintf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
add a comment |
With perl
:
perl -spe 's/TRANSID000K/$n++/e' -- -n=66 < your-file
Or if you need the number to be padded with 0s to a length of 5 (00001, 00010, 00100...):
perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=66 < your-file
With perl
:
perl -spe 's/TRANSID000K/$n++/e' -- -n=66 < your-file
Or if you need the number to be padded with 0s to a length of 5 (00001, 00010, 00100...):
perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=66 < your-file
edited 20 hours ago
answered 20 hours ago
Stéphane ChazelasStéphane Chazelas
313k57593950
313k57593950
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
@RohitPrasad, in which way did it not work? Note that inbash
and all Bourne-like shells but zsh, parameter expansions need to be quoted:-n="$variable"
(or"-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Checkprintf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
add a comment |
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
@RohitPrasad, in which way did it not work? Note that inbash
and all Bourne-like shells but zsh, parameter expansions need to be quoted:-n="$variable"
(or"-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Checkprintf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
Thank you. Is it possible to have n as variable ? I tried perl -spe 's/TRANSIDK000/sprintf "%05d", $n++/e' -- -n=$variable < your-file and it did not work. I am not very familiar with perl syntax.
– Rohit Prasad
19 hours ago
@RohitPrasad, in which way did it not work? Note that in
bash
and all Bourne-like shells but zsh, parameter expansions need to be quoted: -n="$variable"
(or "-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Check printf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
@RohitPrasad, in which way did it not work? Note that in
bash
and all Bourne-like shells but zsh, parameter expansions need to be quoted: -n="$variable"
(or "-n=$variable"
, etc). Is it possible that you variable contain whitespace? Possibly CR character? Check printf %s "$variable" | od -tc -tx1
– Stéphane Chazelas
18 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
Thank you it worked. Much appreciated.
– Rohit Prasad
13 hours ago
add a comment |
Rohit Prasad is a new contributor. Be nice, and check out our Code of Conduct.
Rohit Prasad is a new contributor. Be nice, and check out our Code of Conduct.
Rohit Prasad is a new contributor. Be nice, and check out our Code of Conduct.
Rohit Prasad is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f511081%2freplace-text-in-lines-in-a-file-with-increments%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown