Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
for example, consider a file "abc.txt" has following content
{GRAPHIC_FILE_1 = "E:/ge work/hyperview scripting/name.inp"}
{GRAPHIC_FILE_1 = "E:/ge work/hyperview scripting/result.rst"}
{GRAPHIC_FILE_1 = "E:/ge work/hyperview scripting/abaqusresult.odb"}
So I want a script which will read this .txt file rearch for "*.rst" and replace with given name for example "badapple.rst"
or I will input "result.rst" search for it and replace it with "badapple.rst" keeping remaining all same and copy all other lines to new file
and I cannot change syntax of the text file it should exactly write
{GRAPHIC_FILE_1 = "E:/ge work/hyperview scripting/badapple.rst"}
To replace one string with another in a file, especially where you are changing the length of the string, you are going to find it easiest if you load the whole file into memory, perform the change there, then write it back out again.
set filename "abc.txt"
# Read in the file
set f [open $filename]
set content [read $f]
close $f
# Alter what is on $content here; !!READ BELOW!!
# Write out the file; assumes we've got the newlines in the content already
set f [open $filename "w"]
puts -nonewline $f $content
close $f
So what about that missing piece in the middle? Well, it depends on exactly what change you are trying to make. The details matter a lot here. However, if we are wanting to swap out result.rst for badapple.rst then that's pretty easy with string map (which replaces exact strings with other exact strings):
set content [string map {"result.rst" "badapple.rst"} $content]
Swapping every *.rst is a little trickier, as we need to define what * really matches here. I'm guessing that it doesn't include directory separators or double quotes! Given that, regsub -all is a more appropriate tool.
regsub -all {[^\\/""]+\.rst} $content "badapple.rst" content
Omitting the -all would make it just replace the first matching instance.
The regular expression is:
[^\\/""] — match any character that is not (^) a backslash, forward-slash or double-quote, with some things doubled for various reasons including quoting and readability
+ — one or more of the preceding piece (i.e., one or more non-bad characters)
\. — a full stop (requires a backslash because . is a RE metacharacter)
rst — three literal letter characters
If you're writing your own REs, always put it in {braces}.
Related
I have to delete the last line of file in using tcl script. I know the content so content replacement is also ok. But my content is which has to be replaced by a space or newline character or have to deleted. And my job is in a loop.
Please let me know which is the efficient way, capturing the entire file content each time in loop and replace that string is better or deleting simply the last line.
Please give some script code because I am very new to tcl.
Are we talking about removing the last line from the data on disk or the data in memory? It matters because the approach you use to do those two cases is entirely different.
In memory
Exactly how you manipulate things in memory depends on whether you're representing the data as list of lines or a big string. Both approaches work. (You could be doing something else too, I suppose, but these two are the common obvious ways.)
If you've got your data as a list of lines in memory, you can simply do (assuming you're holding the lines in a variable called theLines):
set theLines [lreplace $theLines end end]
For a particularly large list, there are a few tricks to make it more efficient, but they come down to careful management of references:
# Needs a new enough Tcl (8.5 or 8.6 IIRC)
set theLines [lreplace $theLines[set theLines ""] end end]
Try the first version instead of this if you don't know you need it. Also be aware that if you're wanting to keep the original list of lines around, you should definitely use the first approach.
You might instead have the data in memory as a single big string. In that case, we can use some of Tcl's string searching capabilities to do the job.
set index [string last "\n" $theString end-1]
set theString [string range $theString 0 $index]
The optimisation mentioned above in relation to lreplace is also applicable here (with all the same caveats):
set index [string last "\n" $theString end-1]
set theString [string range $theString[set theString ""] 0 $index]
On disk
When working on disk, things are different. There you need to be much more careful since you can't undo changes easily. There are two general approaches:
Read the file into memory, do the change there (using the techniques above), and do a (destructive) ordinary write out. This is the approach you need when you are doing many other changes anyway (e.g., removing a line from the middle, adding a line to the middle, adding or removing characters from a line in the middle).
set filename "..."
# Open a file and read its lines into a list
set f [open $filename]
set theLines [split [read $f] "\n"]
close $f
# Transform (you should recognise this from above)
set theLines [lreplace $theLines end end]
# Write the file back out
set f [open $filename "w"]
puts -nonewline $f [join $theLines "\n"]
close $f
Find where the data you don't want starts as an offset in the file and truncate the file at that point. This is the right approach with a very large file, but it is rather more sophisticated.
set f [open $filename "r+"]; # NEED the read-write mode!
seek $f -1000 end; # Move to a little bit before the end of the file.
# Unnecessary, and guesswork, but can work and will
# speed things up for a big file very much
# Find the length that we want the file to become. We do this by building a list of
# offsets into the file.
set ptrList {}
while {![eof $f]} {
lappend ptrList [tell $f]
gets $f
}
# The length we want is one step back from the end of the list
set wantedLength [lindex $ptrList end-1]
# Do the truncation!
chan truncate $f $wantedLength
close $f
However you do the disk transformations, make sure you test on a trash file before applying it to anything real! In particular, I've not checked what the truncation method does on a file without a newline at the end. It probably works, but you should test.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'd like to edit multiple (~2000) txt files in Notepad ++. To be more specific: I'd like to narrow the entire text of into a column with newlines.
Like so:
into:
Of course it is not as simple, because the Text is dynamic and contains brackets for certain terms that will later help a search engine (Those will however not become unfunctional when separated with a newline which comes in very handy).
I found out that I can do so easily with the Line Operation "Split Line" in the "Edit" tab. Now I just need to do it with the rest of the files. I wonder if that can be automated? As it is not a macro it could be kind of tricky. Another thing I thought of was using a RegEx in the "Find in Files" option. Something like "find n characters with n spaces in between them" then "replace the exact same chars with the same chars but add a newline at the end".
Or "make a newline every 7 spaces".
Not sure if that is a viable approach, though.
Im curious about what you think about this. Any Suggestions?
In Find in Files, you may use
Find What: (?:^|\G)(\S*(?:\h+\S+){7})\h*
Replace With: $1\n
Do not forget to check the Regular expression radio button at the bottom.
Pattern details:
(?:^|\G) - either start of line or the end of the last successful match
(\S*(?:\h+\S+){7}) - Group 1 later referenced to with $1 backreference in the replacement pattern, capturing 0+ non-whitespace symbols, followed with exactly 7 sequences of 1+ horizontal whitespaces and 1+ non-whitespaces
\h* - zero or more horizontal whitespaces
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have a shell script that uses an array. The script cycle through the entries of the array but for some reason the first and last entry has a problem.
The array:
Queue_Names=( CLQueue DLQ ExpiryQueue )
The for Loop:
for i in “${Queue_Names[#]}”
do
#do stuff
done
I can see in the console and shows that for the first entry it shows: �CLQueue.
The last entry shows: ExpiryQueue�
I'm guessing these are markers to know the start and end of the array. Unfortunately it is interfering with the functionality of the script. I use these Queue names to search for something and it fails to find it because of the added character. How do I get rid of them or is there a code change I do to avoid the problem?
“${Queue_Names[#]}” is not "${Queue_Names[#]}", because “” is not "".
"Smart quotes" aren't recognized as quotes at all in bash; thus, the effect is the same as if the expansion had been unquoted -- string-splitting and glob-expansion on array contents -- with the literal "quotes" grafted around the start and end characters.
You need to use real quotes -- "" -- not opening/closing "smart quotes" created by some word processing software or corporate email tools.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
I am using following code to create a new file cat15 using cat command in UNIX
# cat > cat15
this command adds a new file cat15 in root directory and whatever I type after this command is being stored into the file created. But I am not able to exit from this editor.
In other word, I am not getting Shell prompt symbol #
The cat command reads from STDIN if you don't specify a filename. It continues to do this until it receives an EOF or is killed. You can send an EOF and get your terminal back by typing <ctrl>+d.
What people generally do is to either use
touch filename
or
echo -n > filename
to create an empty file. As Charles correctly notes below, "echo -n" is not always a good idea (though you can usually count on it under "popular" Linux distros); I'd strongly suggest just using touch.
If you just want to create an empty file, regardless of whether one existed or not, you can just use ">" like this:
> cat15
It will clobber anything that already exists by that name.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I have a text file that is processed by a third party. They told me the file is invalid because it contains a non-printable character. What's the best way to find the non-printable character as my normal text editors won't display it. I would prefer a windows, dos, or powershell based solution.
Option #1 - Show All Characters
You can download Notepad++ and open the file there. Then, go to the menu and select View->Show Symbol->Show All Characters. All characters will become visible, but you will have to scroll through the whole file to see which character needs to be removed.
Unfortunately, Notepad++ will automatically convert line endings according to your Edit->EOL Conversion selection, so it won't help if your non-printable characters are CR or LF.
Option #2 - TextFX Zap Non-printable Chars
Alternatively, you could install the TextFX plugin from SourceForge, and use TextFX->TextFX Characters->Zap all non-printable characters to #. This will replace some non-printable characters with a pound sign, but not CR or LF.
Option #3 - Remove BOM Encoding
Lastly, you could use Notepad++, and use Encoding->Convert to UTF8 without BOM. This will remove non-printable characters which occasionally causes issues with certain renderers (VSO).